如何让循环内SendKeys发送的内容在截图前生效,而非全部截图后才显示?
问题根因
所有逻辑都运行在UI主线程上,SendKeys.Send 发出的按键消息需要目标窗口处理消息队列才能生效,但后续的截图、循环逻辑会持续占用UI线程,不会让出时间片给其他窗口处理消息,因此所有按键消息会被堵塞到整个循环执行完毕后才批量触发。
修复方案
你可以在发送按键后、截图前增加消息处理等待逻辑,示例修改后的代码如下:
private void button1_Click(object sender, EventArgs e) { // 先在UI线程取完所有控件值,避免后续跨线程访问问题 int ID = Convert.ToInt32(textBox1.Text); //服装类型 int drawable = Convert.ToInt32(textBox2.Text); //服装数量 int Z = Convert.ToInt32(textBox3.Text); //颜色数量 Thread.Sleep(2000); for(int i = 0; i < drawable + 1; i++) { for (int m = 0; m < Z + 1; m++) { SendKeys.Send("t"); SendKeys.Send("/setclothes " + ID + " " + i + " " + m); // 等待所有按键消息发送处理完成 SendKeys.Flush(); // 处理当前所有待处理的窗口消息 Application.DoEvents(); // 给目标窗口预留150毫秒渲染内容的时间,可根据实际响应速度调整 Thread.Sleep(150); string filename = String.Format(@"D:\Test\{0}_{1}_{2}.png", ID, i, m); Bitmap printscreen = new Bitmap(Screen.PrimaryScreen.Bounds.Width, Screen.PrimaryScreen.Bounds.Height); Graphics graphics = Graphics.FromImage(printscreen as Image); graphics.CopyFromScreen(0, 0, 0, 0, printscreen.Size); printscreen.Save(filename, System.Drawing.Imaging.ImageFormat.Png); // 释放资源避免内存泄漏 graphics.Dispose(); printscreen.Dispose(); } } }
额外优化建议
如果循环次数较多,建议把整个循环逻辑放到Task.Run()中后台执行,避免UI界面卡住,后台线程访问UI控件时需要用Invoke封送到UI线程执行。
内容的提问来源于stack exchange,提问作者Rekviem
相关产品推荐
相关产品推荐

