我只是想知道该用什么方法?在哪种情况下我可以使用此方法。

我最初的想法是RunSynchronously是用于调用异步方法并同步运行该方法,而不会引起像.wait()那样的死锁问题。

但是,根据MSDN



如果任务要在调用线程上运行,为什么在这里需要TaskScheduler?

最佳答案

RunSynchronously将何时启动任务的决定委托(delegate)给当前的任务调度程序(或作为参数传递的任务调度程序)。

我不确定为什么会出现这种情况(可能是内部使用或传统使用),但是很难在当前 .NET 的当前版本中想到一个有用的用例。问题的@Fabjan has a possible explanation in his comment
RunSynchronously要求调度程序同步运行它,但是然后调度程序很可能会忽略该提示,并在线程池线程中运行它,您当前的线程将同步阻塞,直到完成为止。

调度程序不必在当前线程上运行它,也不必立即运行它,尽管我认为这将在通用调度程序(ThreadPoolTask​​Scheduler和通用UI调度程序)上发生。

如果任务已经启动或已完成/发生故障,那么RunSynchronously也会引发异常(这意味着您将无法在异步方法上使用它)。

此代码可以阐明不同的行为:
WaitResult根本不运行任务,它们只是等待当前线程上的任务完成并将其阻止,直到完成为止,因此,如果我们要比较,我们可以将StartWaitRunSynchronously进行比较:

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),它将进入队列。

10-04 17:57