thread.sleep不';无法在C#图形中正常工作
我想画一个像素,5秒钟后再画另一个像素。但在这段代码中,我点击按钮后,需要5秒钟,两个像素同时画。这意味着首先运行thread.sleep,然后设置像素。如何解决thread.sleep不';无法在C#图形中正常工作,c#,delay,C#,Delay,我想画一个像素,5秒钟后再画另一个像素。但在这段代码中,我点击按钮后,需要5秒钟,两个像素同时画。这意味着首先运行thread.sleep,然后设置像素。如何解决 private void button1_Click(object sender, EventArgs e) { Graphics g = panel1.CreateGraphics(); Bitmap bmp = new Bitmap(panel1.Width, panel1.Height)
private void button1_Click(object sender, EventArgs e)
{
Graphics g = panel1.CreateGraphics();
Bitmap bmp = new Bitmap(panel1.Width, panel1.Height);
panel1.BackgroundImage = (Image)bmp;
panel1.BackgroundImageLayout = ImageLayout.None;
bmp.SetPixel(15, 15, Color.Red);
System.Threading.Thread.Sleep(5000);
bmp.SetPixel(17, 17, Color.Red);
}
这是因为您睡在同一个UI线程中。您需要使用另一个线程等待并调用UI来绘制另一个像素,等等
最简单的方法是使用WinForms定时器。这是因为您睡在同一个UI线程中。您需要使用另一个线程等待并调用UI来绘制另一个像素,等等
最简单的方法是使用WinForms定时器。您可以使用async/await不阻塞UI
private async void button1_Click(object sender, EventArgs e)
{
Graphics g = panel1.CreateGraphics();
Bitmap bmp = new Bitmap(panel1.Width, panel1.Height);
panel1.BackgroundImage = (Image)bmp;
panel1.BackgroundImageLayout = ImageLayout.None;
bmp.SetPixel(15, 15, Color.Red);
await Task.Delay(5000); // <---
bmp.SetPixel(17, 17, Color.Red);
}
private async void按钮1\u单击(对象发送方,事件参数e)
{
Graphics g=panel1.CreateGraphics();
位图bmp=新位图(panel1.Width,panel1.Height);
panel1.BackgroundImage=(图像)bmp;
panel1.BackgroundImageLayout=ImageLayout.None;
bmp.SetPixel(15,15,Color.Red);
等待任务。延迟(5000);//您可以使用async/await不阻塞您的UI
private async void button1_Click(object sender, EventArgs e)
{
Graphics g = panel1.CreateGraphics();
Bitmap bmp = new Bitmap(panel1.Width, panel1.Height);
panel1.BackgroundImage = (Image)bmp;
panel1.BackgroundImageLayout = ImageLayout.None;
bmp.SetPixel(15, 15, Color.Red);
await Task.Delay(5000); // <---
bmp.SetPixel(17, 17, Color.Red);
}
private async void按钮1\u单击(对象发送方,事件参数e)
{
Graphics g=panel1.CreateGraphics();
位图bmp=新位图(panel1.Width,panel1.Height);
panel1.BackgroundImage=(图像)bmp;
panel1.BackgroundImageLayout=ImageLayout.None;
bmp.SetPixel(15,15,Color.Red);
等待任务。延迟(5000);//这是因为当你调用线程时,它都发生在同一个线程上。Sleep
你睡眠线程,这样UI就没有机会更新,所以绘图一次完成。试着延迟另一个线程上的第二个点,然后绘制它
bmp.SetPixel(15, 15, Color.Red);
Task.Delay(5000).ContinueWith(t =>
{
bmp.SetPixel(17, 17, Color.Red);
}, TaskScheduler.FromCurrentSynchronizationContext());
这是因为当你调用thread时,所有这些都发生在同一个线程上。Sleep
你睡眠线程,这样UI就没有机会更新,所以绘图一次完成。尝试延迟另一个线程上的第二个点,然后绘制它
bmp.SetPixel(15, 15, Color.Red);
Task.Delay(5000).ContinueWith(t =>
{
bmp.SetPixel(17, 17, Color.Red);
}, TaskScheduler.FromCurrentSynchronizationContext());
有几点意见:
- 您正在创建图形对象,但没有对其执行任何操作
- 当你调用Thread.Sleep时,你正在睡眠,线程也负责绘制你的UI。这就是为什么两个像素同时弹出的原因
如果您正在寻找将位图更改“实时”呈现回winforms UI,那么您还有很多工作要做
比如:
- 创建线程以管理位图的更新
- 创建从该线程返回到UI线程的信号机制,其中有一些有趣的东西需要绘制
- 在更新操作和对UI线程的封送处理调用期间同步对位图的访问
如果没有更多关于你真正想要实现的目标的信息,除了在这里和其他答案中发布的内容之外,没有多少建议可以给你一些评论:
- 您正在创建图形对象,但没有对其执行任何操作
- 当你调用Thread.Sleep时,你正在睡眠,线程也负责绘制你的UI。这就是为什么两个像素同时弹出的原因
如果您正在寻找将位图更改“实时”呈现回winforms UI,那么您还有很多工作要做
比如:
- 创建线程以管理位图的更新
- 创建从该线程返回到UI线程的信号机制,其中有一些有趣的东西需要绘制
- 在更新操作和对UI线程的封送处理调用期间同步对位图的访问
如果没有更多关于您实际要完成的任务的信息,那么除了在此处和其他答案中发布的内容之外,您没有多少建议可以给您您的睡眠会阻塞GUI线程并停止重新绘制。请使用计时器,这样GUI线程就不会被阻塞。将代码写入答案。这是正确的答案。最简单的方法是方法是用等待任务.延迟(5000)
替换系统.Threading.Thread.Sleep(5000)
(与当前问题无关)你从来没有对图形对象做过任何事情。我通常会说你需要记住处理它,但你从来没有使用过它,所以就把它扔掉。你的睡眠会阻碍GUI线程并停止重新绘制。使用计时器,这样GUI线程就不会被阻碍。将代码写入一个答案。这是正确的。最简单的方法要执行此操作,请将System.Threading.Thread.Sleep(5000)
替换为wait Task.Delay(5000)
(与当前问题无关)您从未对Graphics
对象执行过任何操作。我通常会说您需要记住处置它,但您从未使用过它,所以请将其丢弃。您可以删除Graphics g=panel1.CreateGraphics();
它从未被使用过。(或至少处置过)@HFDev这是.Net 4.0任务延迟的延迟(整数毫秒){var tcs=new TaskCompletionSource();new System.Threading.Timer(=>tcs.SetResult(null)).Change(毫秒,-1);返回tcs.Task;}
然后将其与continuouse一起使用,或者使用目标包并使用TaskEx
@QtX。我将代码写入应答(.net 4.5)但那只是在15,15中画一个像素。为什么?如何解决它?@HFDev它应该在5秒后17,17再画一个。你可以删除Graphics g=panel1.CreateGraphics();
它从来没有被使用过。(或者至少要处理它)@HFDev这里是.Net 4.0任务延迟(int毫秒){var tcs=new TaskCompletionSource();new System.Threading.Timer(=>tcs.SetResult(null)).Change(毫秒,-1);返回tcs.Task;}
然后将其与continue一起使用,或者使用目标包并使用TaskEx
@QtX。我将代码写入应答(.net 4.5)但那只是在15,15中画一个像素。为什么?如何解决它?@HFDev它应该在5秒后17,17再画一个。