同步运行任务以及何时执行任务的目的是什么?

时间:2015-01-08 11:32:07

标签: c# multithreading asynchronous

同步运行任务的目的是什么

public static void RunMeSync()
{
  for(int i = 0; i < 9999; i++)
  {
    ListBox1.Items.Add(i.ToString());
  }
}
public static void Main()
{
  Task T1 = new Task(()=>RunMeSync);
  T1.RunSynchronously();
  Task T2 = Task.Run(()=>RunMeSync);
}

这样做是没有意义的吗?什么是同步运行任务的需要?
请考虑以下代码段

public static void Main()
{
  Task T1 = new Task(()=>RunMeSync);
  T1.RunSynchronously();
  RunMeSync();
}

同步运行T1 Synchronously,直接调用RunMeSync吗?

3 个答案:

答案 0 :(得分:2)

  

同步运行T1同样是直接调用RunMeSync吗?

是的,效果是一样的。通过同步运行由您可以直接调用的方法构建的任务,您将无法获得任何收益。

但是,并非所有任务都是这样的:有些是根据您无法访问的方法构建的 - 例如,作为参数传递到您的类中的任务。在其他情况下,任务没有与之关联的命名方法,因为它是从 lambda 或匿名委托构造的。在所有这些情况下,RunSynchronously()提供了一种调用实现任务的逻辑的方法,而不需要知道或担心定义逻辑的方式。

答案 1 :(得分:1)

Task本身只是一个工作单元 - 因此,它与运行方式无关。

完全取决于您根据程序的需求,约束和上下文来确定它的运行方式(虽然默认为可能并行运行)

答案 2 :(得分:1)

名称RunSynchronously有点用词不当,更好的名称是TryToRunSynchronously。方法将等待任务完成,无论它运行的是哪个线程,也许这就是他们选择这个名称的原因。

是的,顾名思义Task不会总是在当前线程中同步运行。如果底层调度程序拒绝内联,则Task仍将排队等待执行并等待它完成。 TaskScheduler.TryExecuteTaskInline决定Task是否是内联的候选者,另一个决定内联任务的参数是可用堆栈的数量。因此,与同步调用方法相同。

当您处理一些非常深的递归算法时,它可能会有所帮助。非常深的递归会导致StackOverflowException,你可以检查你是否有足够的堆栈来进行递归,如果不是只是在另一个线程中执行任务(事实上它是如何实现的)。

考虑我们正在并行化一些工作。我们跨越线程分割工作,并且每个线程都进行一些深度递归。如果您使用传统的递归函数执行此操作,则最终会得到StackOverflowException。但是如果你将递归方法逻辑包装在Task.RunSynchronously中,那么它将自动停止递归并将任务排队到底层调度程序,并在没有足够的堆栈可用时等待它完成。