C#Timer和Task-使用async和await [英] C# Timer and Task- using async and await

查看:726
本文介绍了C#Timer和Task-使用async和await的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有PictureBox的Windows窗体。我想在后台使用Timer和Task检查图像更新并刷新新图像是否可用。



我对使用Task感到困惑,是否需要使用await和async。

我不希望在运行Task时阻止UI。



在这里查看:http:/ /dotnetcodr.com/2014/01/01/5-ways-to-start-a-task-in-net-c/



他使用异步方法和等待,但我发现调用异步方法的唯一方法是使用await。但是那个调用它的方法应该使用await等来调用它。

但是我不能让所有的方法都异步吗?



我还想过使用Tasks和async我不应该等待吗?

过去我使用的是backgroundWorker并且没有等待?!



  void  timerRefreshImage_Elapsed( object  sender,System.Timers.ElapsedEventArgs e )
{
任务t = 任务(()= > RefreshImage ());
t.Start();
}

私有 void RefreshImage()
{
尝试
{
Task.Run(()=> GetCameraImage());
}
catch (例外t)
{
throw t;
}

}





更新图像的最佳方法是什么? ?

解决方案

请参阅我对该问题的评论。你正试图让事情变得更加复杂,特别是使用计时器。首先,定期轮询某事的整个想法非常浪费。请参阅我过去的答案以获得一些解释:网站帐户的应用程序'仪表板' [ ^ ]。



现在,如果我仍然需要进行此轮询,我会做一件简单的事情:创建一个永久工作的线程,在循环中进行采集,循环中的延迟( System.Thread.Sleep(延迟))。现在,问题是将获取的图像发送到UI。实际上不是问题。您不能从非UI线程调用与UI相关的任何内容。相反,您需要使用 Invoke System.Windows.Threading的方法。 Dispatcher (对于Forms或WPF)或 System.Windows.Forms.Control (仅限表单)。



在你的情况下,我会使用调用,而不是 BeginInvoke 。为什么?这会限制线程,因此当UI未准备好接受它时,它不会进行不需要的图像获取。实际上,这个考虑因素是理解定时器为什么非常糟糕的关键(在大多数情况下,实际上是这样):当调用新事件时,是否曾尝试考虑定时器事件的处理尚未完成的情况?远离这些东西总是更好。



你会在我过去的答案中找到它的工作原理和代码样本的详细说明:

Control.Invoke()与Control.BeginInvoke() [ ^ ],

Treeview扫描仪和MD5的问题 [ ^ ]。



另请参阅有关线程的更多参考资料:

如何在vb.net中的其他线程上运行keydown事件 [ ^ ],

在启用禁用+多线程后控制事件未触发 [ ^ ]。



-SA

I have a Windows Form with a PictureBox. I want to use and Timer and Task in the background to check for Image updates and refresh if new Image is available.

I am getting confused using Task and whether I need to use await and async.
I don't want the UI to be blocked while running Task.

Looking here: http://dotnetcodr.com/2014/01/01/5-ways-to-start-a-task-in-net-c/

he uses async method and await but I found only way to call an async method is to use await. But then that method which is calling it should call it using await and so on.
But I can't make all methods async?

Also I thought by using Tasks and async I should not have to wait?
In the past I used backgroundWorker and did not wait?!

void timerRefreshImage_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            Task t = new Task(() => RefreshImage());
            t.Start();
        }

        private void RefreshImage()
        {
            try
            {
                Task.Run(()=>GetCameraImage(true));
            }
            catch (Exception t)
            {
                throw t;
            }

        }



What would be the best approach(es) to update the images?

解决方案

Please see my comment to the question. You are trying to make things more complex than they have to be, especially the use of the timer. First of all, the whole idea of periodic polling of something is pretty bad wasteful. Please see my past answer for some explanations: Application 'dashboard' for website accounts[^].

Now, if I still had to do this polling, I would do the simple thing: create a permanently working thread doing acquisition in the loop, with some delay (System.Thread.Sleep(delay)) in the loop. Now, the problem is sending the acquired image to the UI. Not actually a problem. You cannot call anything related to UI from non-UI thread. Instead, you need to use the method Invoke or BeginInvoke of System.Windows.Threading.Dispatcher (for both Forms or WPF) or System.Windows.Forms.Control (Forms only).

In your case, I would use Invoke, not BeginInvoke. Why? This would throttle the thread, so it would not do unwanted image acquisition when the UI is not ready to accept it. Actually, this consideration is the key to understanding why the timer is really bad (in most cases, actually): did you ever try to take into account the cases when the handling of a timer event is not yet complete when new event is invoked? It's always better to stay away from such things.

You will find detailed explanation of how it works and code samples in my past answers:
Control.Invoke() vs. Control.BeginInvoke()[^],
Problem with Treeview Scanner And MD5[^].

See also more references on threading:
How to get a keydown event to operate on a different thread in vb.net[^],
Control events not firing after enable disable + multithreading[^].

—SA


这篇关于C#Timer和Task-使用async和await的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆