我正在努力了解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中读到的多篇文章之一是这个简短的例子。
答案 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绑定的,是异步编程的经典案例。