C# 正在寻找指南,以了解使用Async和Await进行异步编程的工作原理
我浏览了一个msdn示例代码,其中单击按钮时调用函数,调用例程时使用wait关键字,函数使用async关键字C# 正在寻找指南,以了解使用Async和Await进行异步编程的工作原理,c#,asynchronous,task-parallel-library,async-await,C#,Asynchronous,Task Parallel Library,Async Await,我浏览了一个msdn示例代码,其中单击按钮时调用函数,调用例程时使用wait关键字,函数使用async关键字 private async void StartButton_Click(object sender, RoutedEventArgs e) { int contentLength = await AccessTheWebAsync(); resultsTextBox.Text += St
private async void StartButton_Click(object sender, RoutedEventArgs e)
{
int contentLength = await AccessTheWebAsync();
resultsTextBox.Text +=
String.Format("\r\nLength of the downloaded string: {0}.\r\n", contentLength);
}
async Task<int> AccessTheWebAsync()
{
HttpClient client = new HttpClient();
Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");
DoIndependentWork();
string urlContents = await getStringTask;
return urlContents.Length;
}
void DoIndependentWork()
{
resultsTextBox.Text += "Working . . . . . . .\r\n";
}
他们为什么在这里使用等待。如果我们不使用wait,那么会发生什么
请引导我理解代码的工作原理。我有一个很好的示例,并且代码也非常好
您可以将await
视为“暂停”方法(不阻塞线程),直到等待操作完成。当这种情况发生时,它会将一个未完成的任务返回给调用方法,因此它还可以选择等待
我有一个
您可以将await
视为“暂停”方法(不阻塞线程),直到等待操作完成。发生这种情况时,它会将未完成的任务返回给调用方法,因此它还可以从MSDN中选择等待
等待运算符应用于异步方法中的任务,以暂停方法的执行,直到等待的任务完成。该任务表示正在进行的工作。Wait不会阻止正在执行该任务的线程。相反,它使编译器将异步方法的其余部分注册为等待的任务的延续。控件然后返回给异步方法的调用方。当任务完成时,它调用它的continuation,异步方法的执行在它停止的地方继续
所以当编译器遇到
int contentLength = await AccessTheWebAsync();
它等待访问webasync()
任务完成
请查看MSDN中的此示例:
等待运算符应用于异步方法中的任务,以暂停方法的执行,直到等待的任务完成。该任务表示正在进行的工作。Wait不会阻止正在执行该任务的线程。相反,它使编译器将异步方法的其余部分注册为等待的任务的延续。控件然后返回给异步方法的调用方。当任务完成时,它调用它的continuation,异步方法的执行在它停止的地方继续
所以当编译器遇到
int contentLength = await AccessTheWebAsync();
它等待访问webasync()
任务完成
请看一看这个例子不确定你是否可以通过以下方式更简单地理解这一点,但这就是它对我的帮助:
如您所见,访问webasync
返回任务
,而不仅仅是int
如果您不使用“wait”调用它,您只需要得到任务
对象作为其结果。并且可以进一步(手动)执行该任务:例如,等待任务完成theTask.wait()
并在任务result中获取int
的结果
但是await
会代替您执行所有这些操作,并只返回int
:Task
=>int
就是这样。我不确定你用以下方式理解这一点是否更简单,但这就是它对我的帮助:
如您所见,访问webasync
返回任务
,而不仅仅是int
如果您不使用“wait”调用它,您只需要得到任务
对象作为其结果。并且可以进一步(手动)执行该任务:例如,等待任务完成theTask.wait()
并在任务result中获取int
的结果
但是await
会代替您执行所有这些操作,并只返回int
:Task
=>int
就是这样。等待所做的就是阻塞线程,直到异步操作的结果返回 编辑:对不起,当我说阻塞时,我应该说暂停,因为阻塞会阻止执行继续 Edit2:正如Alex指出的,我应该说“执行被暂停”,而不是线程。基本上,“等待返回之前都会发生,但关键是您似乎正在编写和执行同步代码” 由于异步操作可能需要一段时间(例如web服务调用),因此它们倾向于使用回调来返回结果 如果必须在代码中处理回调,可能会有点混乱,尤其是在等待多个相互依赖的异步任务时。Async/await和Task简化了代码,这样您就可以按照阅读顺序编写异步代码 e、 g.带有回调的标准异步代码示例:
public int CallSomeServiceAndReturnItsValue()
{
int result = 0;
WebService.SomeAsyncServiceCall((svcResult) => { result = svcResult.Value; });
return result;
}
如果您有多个呼叫需要链接:
public int CallSomeServiceAndReturnItsValue()
{
int result = 0;
WebService.GetSomeIdentifier((svcResult) =>
{
var identifier = svcResult.Value;
WebService.GetResult(identifier, (anotherResult) =>
{
result = anotherResult.Value;
}
}
);
return result;
}
正如您所看到的,它开始变得混乱,代码并没有按照感觉自然的顺序阅读。另一种方法是使用回调方法,而不是匿名方法,但回调方法与调用它们的代码相距甚远,因此可能会感到脱节
另一种选择当然是async/await,这更清楚
public int CallSomeServiceAndReturnItsValue()
{
int identifier = await WebService.GetSomeIdentifier();
return await WebService.GetResult(identifier);
}
等待所做的一切就是阻塞线程,直到异步操作的结果返回 编辑:对不起,当我说阻塞时,我应该说暂停,因为阻塞会阻止执行继续 Edit2:正如Alex指出的,我应该说“执行被暂停”,而不是线程。基本上,“等待返回之前都会发生,但关键是您似乎正在编写和执行同步代码” 由于异步操作可能需要一段时间(例如web服务调用),因此它们倾向于使用回调来返回结果 如果必须在代码中处理回调,可能会有点混乱,尤其是在等待多个相互依赖的异步任务时。异步/等待和任务简化
public async Task<int> GetSiteLengthAsync(string url)
{
HttpClient client = new HttpClient(); <= Sync
Task<string> download1 = client.GetStringAsync(url); <= Sync
string site1 = await download1; <= Async (Another thread)
return site1.Length; <= Async (Another thread)
}