如果通过使用Async或async修饰符指定方法是异步方法,则启用以下两个功能...标记的异步方法本身可以通过调用它的方法等待。
但是another page gives this example:
var originalWhen = $routeProvider.when;
$routeProvider.when = function(path, route) {
if (!route.resolve) {
route.resolve = {};
}
angular.extend(route.resolve, {
availableCodes: function($rootScope, serverService) {
if ($rootScope.isAuthenticated) {
return numbersService.getAvailableCodes().$promise.then(function(data) {
$rootScope.availableCodes = data.codes;
});
}
}
});
return originalWhen.call($routeProvider, path, route);
};
在这里,我们看到它调用函数private async Task SumPageSizesAsync()
{
// To use the HttpClient type in desktop apps, you must include a using directive and add a
// reference for the System.Net.Http namespace.
HttpClient client = new HttpClient();
// . . .
Task<byte[]> getContentsTask = client.GetByteArrayAsync(url);
byte[] urlContents = await getContentsTask;
// Equivalently, now that you see how it works, you can write the same thing in a single line.
//byte[] urlContents = await client.GetByteArrayAsync(url);
// . . .
}
not equipped with the async keyword,但调用者能够等待结果。
GetByteArrayAsync
的函数与标记为异步的相同函数之间的区别是什么?答案 0 :(得分:4)
当MSDN说async修饰符允许调用者等待时,MSDN是否错误?
没有。它允许调用者等待重写您的方法以返回Task
/ Task<T>
。但这不是唯一的方法。 任何返回等待的方法(例如Task<bool>
,YieldAwaitable
)都可以让来电者等待。
从调用者的角度来看,返回
Task<T>
的函数与标记为async
的函数之间的区别是什么?
如果正确实施,应该没有任何区别。 async
和await
关键字是编译器帮助您编写异步代码的一种方式。但他们没有必要。你可以(而且你总是可以)在没有它们的情况下编写异步代码。
以Task.Delay
为例。它创建一个任务,设置一个计时器,配置计时器以在一段时间后完成任务并返回任务。它不使用async-await,也不需要。但是通过返回任务,它允许调用者等待它。
实际上,.NET框架中的许多任务返回方法都没有在内部使用async-await,因为它们是“根”异步方法。他们返回任务但没有任务等待自己。
答案 1 :(得分:3)
请勿等待函数,等待Task
或Task<T>
函数返回 1 。在您看到await client.GetByteArrayAsync(url)
的任何示例中,隐藏的隐式Task<byte[]>
会在client.GetByteArrayAsync(url)
和await
之间“传递”。
你的问题类似于问“+
在你做什么时如何工作
int result = 1 + 2;
vs你做什么
int two = 2;
int result = 1 + two;
文档说明它是为了将两个数字加在一起,但我没有在第二个例子中添加两个数字我正在添加数字和变量。“
1:它比这更完整,但99%的时间只是这样想。
答案 2 :(得分:2)
来自async/await faq(强调我的):
“async”关键字在应用于方法时的作用是什么?
当您使用“async”关键字标记方法时,您真的在说 编译器有两件事:
- 您告诉编译器您希望能够在方法中使用“await”关键字(您可以使用await关键字if 并且只有当它所在的方法或lambda被标记为async时)。这样做 所以,你告诉编译器使用状态编译方法 机器,这样该方法就可以暂停然后恢复 在等待点异步。
- 您告诉编译器“解除”方法的结果或可能出现在返回类型中的任何异常。对于一种方法 返回任务或任务,这意味着任何返回的值或 在方法中未处理的异常存储在 结果任务。对于返回void的方法,这意味着任何 异常通过任何方式传播到调用者的上下文 “SynchronizationContext”在方法时是最新的 初始调用。
醇>
因此,将它视为普通旧异步.NET模型的语法糖:更多的编译器检查,更少的代码,以及对调用者的角度完全无动于衷(调用者要么在async
方法中等待结果,要么使用其他方法TPL原语,甚至是块。)
实际上,如果您选中source code of the GetByteArrayAsync method,它只是GetContentAsync方法的一个包装器,用Task
和TaskCompletionSource
构造结果private Task<T> GetContentAsync<T>(Uri requestUri, HttpCompletionOption completionOption, T defaultValue,
Func<HttpContent, Task<T>> readAs)
{
TaskCompletionSource<T> tcs = new TaskCompletionSource<T>();
GetAsync(requestUri, completionOption).ContinueWithStandard(requestTask =>
{
if (HandleRequestFaultsAndCancelation(requestTask, tcs))
{
return;
}
HttpResponseMessage response = requestTask.Result;
if (response.Content == null)
{
tcs.TrySetResult(defaultValue);
return;
}
try
{
readAs(response.Content).ContinueWithStandard(contentTask =>
{
if (!HttpUtilities.HandleFaultsAndCancelation(contentTask, tcs))
{
tcs.TrySetResult(contentTask.Result);
}
});
}
catch (Exception ex)
{
tcs.TrySetException(ex);
}
});
return tcs.Task;
}
并继续传递样式。
{{1}}
答案 3 :(得分:1)
async
修饰符可让您在该方法中使用await
关键字 。在标记为Task
的方法中,可以等待任何async
- Task
表示正在进行的活动,该活动在返回给调用方时可能已经完成,也可能尚未完成。
答案 4 :(得分:-1)
据我所知,等待 等待。 C
是。
Task
- 用于方法。 The marked async method can itself be awaited
并不需要为了等待(这是您在Task
中所做的事情)。
这也回答了第2部分 - 不同之处在于,无法等待返回await getContentsTask
并且不标记为Task
的那个。这是MSDN在引用文中所说的内容。
(当然,我可能错了。)