Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/267.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
thread.sleep不';无法在C#图形中正常工作_C#_Delay - Fatal编程技术网

thread.sleep不';无法在C#图形中正常工作

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)

我想画一个像素,5秒钟后再画另一个像素。但在这段代码中,我点击按钮后,需要5秒钟,两个像素同时画。这意味着首先运行thread.sleep,然后设置像素。如何解决

 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再画一个。