我是异步编程的新手,所以在看了一些异步示例代码之后,我想到了写一个简单的异步代码
我创建了一个简单的 Winform 应用程序,并在 Form 中编写了以下代码。但它就是不起作用
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);
}
有人可以在这里放点灯吗..
最佳答案
列出的方法返回类型是Task<string>
.您正在尝试返回 string
.它们不一样,也不存在从字符串到 Task<string>
的隐式转换,因此出现错误。
您可能会将其与 async
混淆返回值自动包装在 Task
中的方法由编译器。目前该方法不是异步方法。你几乎肯定是想这样做:
private async Task<string> methodAsync()
{
await Task.Delay(10000);
return "Hello";
}
有两个关键变化。首先,该方法标记为 async
,这意味着返回类型包含在 Task
中, 使方法编译。接下来,我们不想进行阻塞等待。作为一般规则,当使用 await
模型总是尽可能避免阻塞等待。 Task.Delay
是将在指定的毫秒数后完成的任务。通过 await
- 在该任务中,我们正在有效地执行非阻塞等待时间(实际上,该方法的其余部分是该任务的延续)。
如果您更喜欢 4.0 的方式,而不使用 await
,你可以这样做:
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();
});
}
关于c# - 无法将类型 'string' 隐式转换为 'System.Threading.Tasks.Task<string>',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14658001/