有人可以解释这对同步方法意味着什么吗?如果我尝试将方法更改为async
,那么VS会抱怨它。
这有效:
public Task MethodName()
{
return Task.FromResult<object>(null);
}
这不起作用:
public async Task MethodName()
{
return Task.FromResult<object>(null);
}
所以基本上我想知道这究竟是什么意思:Task.FromResult<object>(null);
答案 0 :(得分:166)
async
方法与普通方法不同。无论您从async
方法返回什么内容都包含在Task
。
如果您没有返回任何值(无效),它将被包裹在Task
中,如果您返回int
,它将被包裹在Task<int>
中,依此类推。
如果您的异步方法需要返回int
,则会将方法的返回类型标记为Task<int>
,并且您将返回纯int
而不是Task<int>
。编译器会将int
转换为Task<int>
。
private async Task<int> MethodName()
{
await SomethingAsync();
return 42;//Note we return int not Task<int> and that compiles
}
Sameway,当您返回Task<object>
时,您的方法的返回类型应为Task<Task<object>>
public async Task<Task<object>> MethodName()
{
return Task.FromResult<object>(null);//This will compile
}
由于您的方法返回Task
,因此不应返回任何值。否则它将无法编译。
public async Task MethodName()
{
return;//This should work but return is redundant and also method is useless.
}
请注意,没有await
语句的异步方法不是async
。
答案 1 :(得分:36)
使用async时需要使用await关键字,函数返回类型应该是泛型以下是返回值的示例:
public async Task<object> MethodName()
{
return await Task.FromResult<object>(null);
}
以下是没有返回值的示例:
public async Task MethodName()
{
await Task.CompletedTask;
}
阅读以下内容:
TPL:http://msdn.microsoft.com/en-us/library/dd460717(v=vs.110).aspx和任务:http://msdn.microsoft.com/en-us/library/system.threading.tasks(v=vs.110).aspx
异步:http://msdn.microsoft.com/en-us/library/hh156513.aspx 等待:http://msdn.microsoft.com/en-us/library/hh156528.aspx
答案 2 :(得分:19)
添加async关键字只是语法糖,可以简化状态机的创建。从本质上讲,编译器会使用您的代码;
public async Task MethodName()
{
return null;
}
然后把它变成;
public Task MethodName()
{
return Task.FromResult<object>(null);
}
如果您的代码有任何await
个关键字,编译器必须将您的方法转换为一个类来表示执行它所需的状态机。在每个await
关键字中,变量的状态和堆栈将保留在类的字段中,类将自己添加为您正在等待的任务的完成挂钩,然后返回。
当该任务完成后,您的任务将再次执行。因此,在方法的顶部添加了一些额外的代码,以恢复变量的状态并跳转到代码的下一个平板。
有关血腥的例子,请参阅What does async & await generate?。
这个过程与编译器使用yield语句处理迭代器方法的方式有很多共同之处。
答案 3 :(得分:2)
public static async Task<string> MyTask()
{
//C# anonymous AsyncTask
return await Task.FromResult<string>(((Func<string>)(() =>
{
// your code here
return "string result here";
}))());
}
答案 4 :(得分:0)
为了从异步方法中获得正确的响应,您需要在调用这些任务方法时进行等待。这将等待将其转换回返回的值类型,而不是任务类型。
例如var content =等待StringAsyncTask(
其中公共异步任务<< strong>字符串>,其中StringAsyncTask())