代码示例

时间:2016-03-02 19:13:11

标签: c# .net asynchronous

我正在努力了解C#async / await关键字的目标是什么,你可以通过提供代码示例来帮助我吗?

我准备了我能想象的最简单的代码片段,它使用线程来避免阻塞方法。在研究了异步/等待文章后,我认为async / await可能会变得很方便。然而,我遇到了一些问题,为了清楚起见,我不会描述这些问题。

那么,通过引入这些关键字可以改进以下代码吗?如果可以,可以如何改进?

    public void ReturnASAP()
    {
        var thread = new Thread(() =>
        {
            LongRunningTask(DoneCallback);
        });

        thread.Start();
    }

    private void LongRunningTask(Action doneCallback)
    {
        Thread.Sleep(2000); //long running operation
        doneCallback();
    }

    private void DoneCallback()
    {
        System.Console.WriteLine("Long running task is done! Huray!");
    }

如果这不是async / await有用的情况,你能提供类似的简单代码吗?请不要只提供文字描述它们的用途,我只是放弃了尝试理解它们而没有简明扼要的代码示例。

谢谢!

PS:有很多关于异步/等待使用的问题,但它们不提供小而简单的代码片段,对我来说似乎不太清楚,请不要将此问题重复。

编辑:

事实证明,我提供的示例确实太简单,无法获得async / await的好处。我自己想出了另一个样本。好的,这里是不使用async / await的代码,它需要以非阻塞方式执行两个顺序任务:

    //need to execute LongRunningTask2 after LongRunningTask is finished
    public override void ReturnASAP()
    {
        var thread = new Thread(() =>
        {
            LongRunningTask(() =>
            {
                DoneCallback(DoneCallback2);
            });
        });

        thread.Start();
    }

    private void LongRunningTask(Action doneCallback)
    {
        Thread.Sleep(2000); //long running operation
        doneCallback();
    }

    private void LongRunningTask2(Action doneCallback2)
    {
        Thread.Sleep(2000); //long running operation 2
        doneCallback2();
    }

    private void DoneCallback(Action doneCallback2)
    {
        System.Console.WriteLine("Long running task is done! Huray!");
        System.Console.WriteLine("Starting Long running task 2");

        var thread = new Thread(() =>
        {
            LongRunningTask2(DoneCallback2);
        });

        thread.Start();
    }

    private void DoneCallback2()
    {
        System.Console.WriteLine("Long running task 2 is done! Huray!");
    }

用async / await重写它看起来好多了:

    public override async void ReturnASAP()
    {
        await LongRunningTask();

        System.Console.WriteLine("Long running task is done! Huray!");
        System.Console.WriteLine("Starting Long running task 2");

        await LongRunningTask2();

        System.Console.WriteLine("Long running task 2 is done! Huray!");
    }

    private Task LongRunningTask()
    {
        var thread = new Thread(() =>
        {
            Thread.Sleep(2000); //long running operation
        });

        thread.Start();
        return Task.FromResult(0);
    }

    private Task LongRunningTask2()
    {
        var thread = new Thread(() =>
        {
            Thread.Sleep(2000); //long running operation 2
        });

        thread.Start();
        return Task.FromResult(0);
    }

这就是我所需要的,谢谢你们,无论如何,你的提示帮助我提出了解决方案。我希望在async / await中读到的多篇文章之一是这个简短的例子。

1 个答案:

答案 0 :(得分:1)

您的代码的异步/等待版本(可以说)是:

public async Task ReturnASAP()
{
    var task = LongRunningTask();   //1

    DoSomeLogic()   //3

    await task; //4

    //Do some more logic here //6
}

private async Task LongRunningTask()
{
    await Task.Delay(2000); //2
    System.Console.WriteLine("Long running task is done! Huray!"); //5
}

数字表示执行行的顺序。这段代码和你的代码之间的一个很大的区别是,这段代码是完全单线程的,并且线程不会被阻止。

  

如果这不是async / await有用的情况,你能提供类似的简单代码吗?

鉴于下面的评论,你的例子不是async / await派上用场的情况。在你的代码中,你产生了一个新的线程,与主线程并行执行一些cpu绑定工作 - async / await是关于异步编程,而不是并行编程。在我的示例中,LongRunningTask()是I / O绑定的,是异步编程的经典案例。