不能隐式地将types“string”转换为“System.Threading.Tasks.Task <string>”

我是新来的asynchronous编程,所以经过一些asynchronous示例代码,我想写一个简单的asynchronous代码

我创build了一个简单的Winform应用程序,并在表单中写下了以下代码。 但它只是不工作

private Task<string> methodAsync() { Thread.Sleep(10000); return "Hello"; //Error: Cannot implicitly convert type 'string' to 'System.Threading.Tasks.Task<string>' } private async void button1_Click(object sender, EventArgs e) { string s = await methodAsync(); MessageBox.Show(s); } 

有人可以在这里放一些灯光..

列出的方法的返回types是Task<string> 。 你正在试图返回一个string 。 他们是不一样的,也没有从string隐式转换为Task<string> ,因此错误。

你可能会用一个async方法混淆这个方法,在这个方法中,编译器自动将返回值包装在一个Task 。 目前该方法不是一个asynchronous方法。 你几乎肯定是这样做的:

 private async Task<string> methodAsync() { await Task.Delay(10000); return "Hello"; } 

有两个关键的变化。 首先,方法被标记为async ,这意味着返回types被包装在一个Task ,使得该方法被编译。 接下来,我们不想阻止等待。 一般来说,使用await模式时,请尽量避免阻塞等待。 Task.Delay是在指定的毫秒数之后完成的任务。 通过await那个任务,我们正在有效地执行一个非阻塞等待的时间(实际上方法的其余部分是该任务的延续)。

如果你喜欢4.0的方式,不用await ,你可以这样做:

 private Task<string> methodAsync() { return Task.Delay(10000) .ContinueWith(t => "Hello"); } 

第一个版本将会被编译成或多或less的东西,但是它将会有一些额外的样板代码来支持error handling和其他的functionawait我们在这里没有使用。

如果你的Thread.Sleep(10000)真的只是一个长时间运行的方法的占位符,而不是等待一段时间,那么你需要确保工作是在另一个线程完成的,而不是当前的上下文。 最简单的方法是通过Task.Run

 private Task<string> methodAsync() { return Task.Run(()=> { SomeLongRunningMethod(); return "Hello"; }); } 

或者更可能:

 private Task<string> methodAsync() { return Task.Run(()=> { return SomeLongRunningMethodThatReturnsAString(); }); } 

使用FromResult方法

 public async Task<string> GetString() { System.Threading.Thread.Sleep(5000); return await Task.FromResult("Hello"); } 

除了像@Servy指出的async使用问题之外,另一个问题是您需要通过调用Task.Result从Task<T>显式获取T 请注意,Result属性将阻止asynchronous代码,并应谨慎使用。

尝试:

 private async void button1_Click(object sender, EventArgs e) { var s = await methodAsync(); MessageBox.Show(s.Result); }