同步运行任务的目的是什么
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吗?
答案 0 :(得分:2)
同步运行
T1
同样是直接调用RunMeSync
吗?
是的,效果是一样的。通过同步运行由您可以直接调用的方法构建的任务,您将无法获得任何收益。
但是,并非所有任务都是这样的:有些是根据您无法访问的方法构建的 - 例如,作为参数传递到您的类中的任务。在其他情况下,任务没有与之关联的命名方法,因为它是从 lambda 或匿名委托构造的。在所有这些情况下,RunSynchronously()
提供了一种调用实现任务的逻辑的方法,而不需要知道或担心定义逻辑的方式。
答案 1 :(得分:1)
Task
本身只是一个工作单元 - 因此,它与运行方式无关。
完全取决于您根据程序的需求,约束和上下文来确定它的运行方式(虽然默认为可能并行运行)
答案 2 :(得分:1)
名称RunSynchronously
有点用词不当,更好的名称是TryToRunSynchronously
。方法将等待任务完成,无论它运行的是哪个线程,也许这就是他们选择这个名称的原因。
是的,顾名思义Task
不会总是在当前线程中同步运行。如果底层调度程序拒绝内联,则Task仍将排队等待执行并等待它完成。 TaskScheduler.TryExecuteTaskInline决定Task是否是内联的候选者,另一个决定内联任务的参数是可用堆栈的数量。因此,不与同步调用方法相同。
当您处理一些非常深的递归算法时,它可能会有所帮助。非常深的递归会导致StackOverflowException
,你可以检查你是否有足够的堆栈来进行递归,如果不是只是在另一个线程中执行任务(事实上它是如何实现的)。
考虑我们正在并行化一些工作。我们跨越线程分割工作,并且每个线程都进行一些深度递归。如果您使用传统的递归函数执行此操作,则最终会得到StackOverflowException
。但是如果你将递归方法逻辑包装在Task.RunSynchronously
中,那么它将自动停止递归并将任务排队到底层调度程序,并在没有足够的堆栈可用时等待它完成。