对异步执行顺序感到困惑

时间:2018-07-14 03:01:18

标签: c# asp.net asynchronous

所以我一直在尝试异步编程,现在我对这里发生的事情不知所措。在我的假设情况下,我有一个将一些数据保存到数据库的应用程序,当执行此操作时,我想触发一种方法来在要保存的新版本和数据库中的现有版本之间创建差异。这是一个缓慢的操作,我不希望用户等待,因为这可以在后台完成。在下面链接的示例中,我希望输出为:

Starting
Processing Diff
Log Diff Initiated
Diff processed

但是我看到的是:

Starting
Processing Diff
Diff processed
Log Diff Initiated

我可以理解,根据执行的时间,处理差异和日志差异启动会混杂在一起,但是我绝对希望日志差异启动应始终在差异处理之前,因为在主要情况下,我没有说要等待日志差异,因此执行应该立即继续LogDiff在单独的线程中异步执行。谁能解释为什么会这样?

public static void Main()
{
    Console.WriteLine("Starting");
    LogDiff();
    Console.WriteLine("Log Diff Initiated");
}

public static async Task LogDiff()
{
    var results = await GetDiff("Processing Diff");
    Console.WriteLine(results);
}

public static async Task<string> GetDiff(string str)
{
    Console.WriteLine(str);
    Thread.Sleep(2000);
    return "Diff processed";
}

https://dotnetfiddle.net/IdFgIU

1 个答案:

答案 0 :(得分:2)

这是因为Thread.Sleep正在阻止该过程。改为致电Task.Delay,您会看到区别:

Starting
Processing Diff
Log Diff Initiated
Diff processed

测试代码:

static void Main(string[] args)
{
    Console.WriteLine("Starting");
    var task = LogDiff();
    Console.WriteLine("Log Diff Initiated");
    /// DO WHATEVER YOU WANT THEN WAIT TASK BELOW
    task.Wait();
}

public static async Task LogDiff()
{
    var results = await GetDiff("Processing Diff");
    Console.WriteLine(results);
}

public static async Task<string> GetDiff(string str)
{
    Console.WriteLine(str);
    await Task.Delay(2000);
    return "Diff processed";
}

如果您使用.NET 4.0和更高版本:

public static Task Delay(double milliseconds)
{
    var tcs = new TaskCompletionSource<bool>();
    System.Timers.Timer timer = new System.Timers.Timer();
    timer.Elapsed += (obj, args) =>
    {
        tcs.TrySetResult(true);
    };
    timer.Interval = milliseconds;
    timer.AutoReset = false;
    timer.Start();
    return tcs.Task;
}