2013-02-02 78 views
40

我是新来的异步编程,所以通过一些异步示例代码去后,我想编写一个简单的异步代码无法隐式转换类型“字符串”到“System.Threading.Tasks.Task <string>”

我的创建了一个简单的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); 
} 

可能有人请把一些光在这里..

回答

68

方法的上市返回类型为Task<string>。您正在尝试返回string。它们不一样,也没有从字符串到Task<string>的隐式转换,因此是错误。

您可能会将此与async方法混淆,其中返回值被编译器自动封装到Task中。目前该方法不是异步方法。你几乎肯定意味着要这样做:

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

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

如果你喜欢这样做,而无需使用await的4.0的方式,你可以这样做:

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

第一个版本将编译下来的东西,或多或少是这样的,但它会一些额外的样板代码用于支持错误处理和await的其他功能,我们在这里没有使用。

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

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

或者更可能的:

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

我怎么能明确地包裹在''Task' string'?OR没有任何方法可以在被调用的方法(methodAsync在这种情况下)中不使用'async'和'await'来返回Task或Task ? – dotNETbeginner

+0

@dotNETbeginner否 –

+1

@Aniket不,你错了,有很多方法显式包装一个字符串的任务。我将编辑一个解决方案。 – Servy

12

除了有问题的使用async由@Servy指出,另一个问题是,你需要明确通过调用Task.Result从Task<T>获得T。请注意,Result属性会阻止异步代码,应谨慎使用。

尝试:

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

虽然这可能不是强烈推荐的,但有一个例子我想在'catch {}'内找回'Task '的内容。我无法'等待'和'.ToString()'产生不正确的结果。这符合法案。 – doubleJ

13

使用FromResult方法

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

感谢这正是我所需要的,其他答案都没有提供。 –

+1

最佳答案。重点。 – BaBu

+1

据我可以告诉这个答案是最好的方式来实现一个接口定义任务与同步的实现 –

相关问题