我只是想知道该用什么方法?在哪种情况下我可以使用此方法。
我最初的想法是RunSynchronously
是用于调用异步方法并同步运行该方法,而不会引起像.wait()
那样的死锁问题。
但是,根据MSDN,
如果任务要在调用线程上运行,为什么在这里需要TaskScheduler?
最佳答案
RunSynchronously
将何时启动任务的决定委托(delegate)给当前的任务调度程序(或作为参数传递的任务调度程序)。
我不确定为什么会出现这种情况(可能是内部使用或传统使用),但是很难在当前 .NET 的当前版本中想到一个有用的用例。问题的@Fabjan has a possible explanation in his comment。RunSynchronously
要求调度程序同步运行它,但是然后调度程序很可能会忽略该提示,并在线程池线程中运行它,您当前的线程将同步阻塞,直到完成为止。
调度程序不必在当前线程上运行它,也不必立即运行它,尽管我认为这将在通用调度程序(ThreadPoolTaskScheduler和通用UI调度程序)上发生。
如果任务已经启动或已完成/发生故障,那么RunSynchronously
也会引发异常(这意味着您将无法在异步方法上使用它)。
此代码可以阐明不同的行为:Wait
和Result
根本不运行任务,它们只是等待当前线程上的任务完成并将其阻止,直到完成为止,因此,如果我们要比较,我们可以将Start
和Wait
与RunSynchronously
进行比较:
class Scheduler : TaskScheduler
{
protected override void QueueTask(Task task) =>
Console.WriteLine("QueueTask");
protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
{
Console.WriteLine("TryExecuteTaskInline");
return false;
}
protected override IEnumerable<Task> GetScheduledTasks() => throw new NotImplementedException();
}
static class Program
{
static void Main()
{
var taskToStart = new Task(() => { });
var taskToRunSynchronously = new Task(() => { });
taskToStart.Start(new Scheduler());
taskToRunSynchronously.RunSynchronously(new Scheduler());
}
}
如果尝试注释Start或
RunSynchronously
并运行代码,您将看到Start
尝试将任务排入调度程序,而RunSynchronously
尝试内联执行该任务,如果失败(返回false),它将进入队列。