【问题标题】:Task vs Thread vs background worker for a lifetime method终身方法的任务 vs 线程 vs 后台工作者
【发布时间】:2018-10-23 18:19:04
【问题描述】:

我对这一切有点困惑。我需要在我的应用程序中创建一个生命周期方法,它将与 asp net web 服务通信,它会返回一些结果。只要我的应用程序在运行,这个方法就永远不会停止。

Method-1 创建任务。

 t=Task.Run(()=>ffAsync());

 async void ffAsync()
 {
    while (true)
    {
      await Task.Delay(5000);
      Console.WriteLine("Reading from server every 5 seconds");
    }
 }

使用后台工作者的方法2

Timer t = new Timer();   
t.Interval = 5000;    
timer1.Enabled = true;  
timer1.Tick += new 
System.EventHandler(OnTimerEvent);

private void OnTimerEvent(object sender, EventArgs e) 
{
 backgroundWorker1.RunWorkerAsync();
}

使用线程的方法3

new Thread(() =>
{
   Thread.CurrentThread.IsBackground = true;
   while(true)
   {
      Thread.Sleep(5000);
      Console.WriteLine("Run every 5 seconds");
   }
 }).Start();

哪种方法对我来说更有效? 还有另一个优化问题,最好使用 task.delay(x),Thread.Sleep(x) 每隔 x 秒运行一次循环,还是创建一个计时器(如我的秒数示例),它将每 x 触发一次我的事件秒?

【问题讨论】:

  • 您关心可取消性吗?你关心管理主线程的异常吗?如果您希望工作“永远”并行进行,您可能不想用完线程池线程;对我来说,在您创建并让其运行的线程上运行会更有意义。
  • 你确定在方法1中需要tokenSource吗?我不认为你这样做。如果这个线程会一直运行到你的应用程序死掉,那么你就不需要它了。或者我在这里错过了什么?如果我理解正确,当所有前台线程都完成后,应用程序将关闭,并且它会破坏所有后台线程。下一个问题:你需要这个方法的结果吗?如果你这样做了,那么你应该使用Task,如果你不这样做,那么你应该使用Thread。
  • 在某些情况下,我会在 ui 线程中从我的方法返回一些结果。例如,如果服务器有一些结果,我将打开一个新表单来通知客户端这是关于什么的。在我的应用程序中,它会给我带来更好的性能和速度吗?
  • 另外哪种方法更受欢迎?使用时间或任务延迟?
  • 永远保持线程,主要是在睡觉,这通常不是一个明智的主意。 1和2没有本质区别,Task.Delay也用了Timer,只是看不到而已。除了一个令人讨厌的小细节,如果你实际做的事情超过 5 秒,那么 BackgroundWorker 会提醒你这件事,但有一个例外。该任务只需要超过 5 秒,现在已经完成了。

标签: c# multithreading task backgroundworker


【解决方案1】:

在我的情况下哪种方法更有效?

这些都不对。他们都做后台工作,这对于 IO 绑定任务是错误的。

你不会雇佣一个工人什么都不做,每天睡 23 小时 59 分 59.9999 秒,做 0.0001 秒的工作。所以你也不应该雇佣一个线程来做这件事。

异步 ​​IO 应该被编写为使用异步,并且应该在任何需要 IO 结果的上下文上运行。不要使用Task.Run。在循环内使用异步 IO!

使用Task.DelayThread.Sleep 还是创建Timer 更好?

不要雇佣工人然后让他们睡觉。要么使用延迟,要么做一个计时器。选择哪一个更适合您的程序结构。但重要的是所有工作流都应该在主线程上完成,并且 IO 调用必须是异步的

【讨论】:

  • 如果我的主线程是 UI 线程 (Winforms/WPF),并且我让它完成“所有工作流程”,它如何有时间刷新 UI 并允许响应式 UI?
  • @joedotnot:通过确保 (1) 对高延迟 IO 操作的所有等待都是异步的,以及 (2) 执行的每个 CPU 计算在执行异步之前花费的时间少于 30 毫秒某种产量。如果你这样做了,那么 UI 的响应速度将比人类感知它的速度更快,并且它看起来会很流畅。
  • 听起来很合理,但是我如何提供一个异步 IO 来返回一个任务而不使用里面的任务呢?我知道有内置的异步方法。但是我是否需要使用本机代码来实现异步 API?
  • @joe:恐怕我不明白你的问题。也许这会有所帮助? docs.microsoft.com/en-us/dotnet/standard/io/…
  • @joe:我不知道如何回答你的问题。这对我来说很难,这是肯定的。我非常擅长为编程语言构建语义分析器,并且对异步 IO 的实现细节几乎一无所知。这就是为什么我把这份工作留给了这方面的专家。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-11
  • 1970-01-01
  • 2013-01-18
  • 1970-01-01
  • 2013-06-05
  • 2022-01-19
  • 1970-01-01
相关资源
最近更新 更多