在Microsoft的example中,该方法的返回类型为Task<int>
示例1:
async Task<int> AccessTheWebAsync()
{
// You need to add a reference to System.Net.Http to declare client.
HttpClient client = new HttpClient();
// GetStringAsync returns a Task<string>. That means that when you await the
// task you'll get a string (urlContents).
Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");
// You can do work here that doesn't rely on the string from GetStringAsync.
DoIndependentWork();
// The await operator suspends AccessTheWebAsync.
// - AccessTheWebAsync can't continue until getStringTask is complete.
// - Meanwhile, control returns to the caller of AccessTheWebAsync.
// - Control resumes here when getStringTask is complete.
// - The await operator then retrieves the string result from getStringTask.
string urlContents = await getStringTask;
// The return statement specifies an integer result.
// Any methods that are awaiting AccessTheWebAsync retrieve the length value.
return urlContents.Length;
}
在第二个例子中,它使用async和await,但是不返回任何类型的任务&lt;&gt;,为什么?
示例2:
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
ReadCharacters();
}
static async void ReadCharacters()
{
String result;
using (StreamReader reader = File.OpenText("existingfile.txt"))
{
Console.WriteLine("Opened file.");
result = await reader.ReadToEndAsync();
Console.WriteLine("Contains: " + result);
}
}
}
}
第三,在第一个例子中,是否可以返回一个数组(字符串)?
答案 0 :(得分:7)
在第二个例子中,它使用async和await,但是不返回a 任务类型&lt;&gt;,为什么?
他们犯了一个错误。每当您创建一个异步并且没有返回值的方法时,它应该返回Task
。唯一的例外是事件处理程序,您需要保持与委托签名的兼容性,但事实并非如此。可以将Task
视为异步方法的void
等价物。
为什么您实际想要返回Task
而不是void
?因为返回Task
允许您监视执行状态,并且还允许您正确处理封装在正在进行的操作中的任何异常。
例如,考虑一个抛出的async void
方法:
public async void WaitAndThrowAsync()
{
await Task.Delay(1000);
throw new Exception("yay");
}
public void CallWaitAndThrowAsync()
{
// What happens when it throws here?
WaitAndThrowAsync();
}
当你调用它时,你无法真正处理方法内部发生的异常,它会被激活并忘记&#34;对于呼叫站点。但是当您公开Task
时,您现在可以通过异步等待来更好地处理该异常:
public async Task WaitAndThrowAsync()
{
await Task.Delay(1000);
throw new Exception("yay");
}
public async Task CallWaitAndThrowAsync()
{
try
{
await WaitAndThrowAsync();
}
catch (Exception e)
{
// Do something.
}
}
第三,在第一个例子中,是否可以返回一个 阵列(字符串)?
是的,返回Task<string[]>
:
public async Task<string> GetArrayAsync()
{
HttpClient client = new HttpClient();
var responseStream = await client.GetStreamAsync("http://msdn.microsoft.com");
using (var streamReader = new StreamReader(responseStream))
{
return await streamReader.ReadToEndAsync();
}
}
当您标记方法async
时,编译器将隐式为您创建Task
。如果您有返回类型,则生成的任务为Task<T>
,其中T
是您的返回类型。
答案 1 :(得分:1)
第二个例子不是一个好例子:使用extension LAContext {
func canEvaluatePolicyThrowing(policy: LAPolicy) throws {
var error : NSError?
canEvaluatePolicy(policy, error: &error)
if let error = error { throw error }
}
}
,不可能等待异步方法。 async void
仅应用于事件处理程序。
对于你的第二个问题,是的,它可以返回一个字符串数组。
只需使用async void
。
我真的建议您阅读Stephen Cleary:https://msdn.microsoft.com/en-us/magazine/jj991977.aspx
中的这篇优秀文章文章中的一些最佳做法:
答案 2 :(得分:0)
第二个不是根据guidelines specified by Microsoft:
返回类型是以下类型之一: - 如果您的方法有一个返回语句,其中操作数的类型为TResult,则为Task。 - 如果您的方法没有return语句或者没有操作数的return语句,则执行任务。 - 如果您正在编写异步事件处理程序,则为Void(Visual Basic中的Sub)。
为什么方法应该返回Task
或Task<T>
?
每个返回的任务代表正在进行的工作。任务封装有关异步进程状态的信息,最终是进程的最终结果,或者如果进程没有成功则进程引发的异常。
因此,当您使用void
时,您将丢失信息。您丢弃实际的任务进度和执行信息。因此,对于void
返回类型,请使用Task
。对于任何其他类型,请使用Task<T>
,其中T
是实际的返回类型。
某些方法可以返回void
,但这对事件处理程序或启动方法是禁止的:
异步方法也可以是Sub方法(Visual Basic)或具有void返回类型(C#)。此返回类型主要用于定义事件处理程序,其中需要void返回类型。异步事件处理程序通常用作异步程序的起点。