C# 无法将类型“字符串”隐式转换为“System.Threading.Tasks.Task<string>”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14658001/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Cannot implicitly convert type 'string' to 'System.Threading.Tasks.Task<string>'
提问by dotNETbeginner
I am new to asynchronous programming, so after going through some async sample codes, I thought of writing a simple async code
我是异步编程的新手,所以在经历了一些异步示例代码之后,我想到了写一个简单的异步代码
I created a simple Winform application and inside the Form I wrote the following code. But its just not working
我创建了一个简单的 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);
}
Could someone please put some light here..
有人可以在这里放一些灯吗..
采纳答案by Servy
The listed return type of the method is Task<string>
. You're trying to return a string
. They are not the same, nor is there an implicit conversion from string to Task<string>
, hence the error.
列出的方法的返回类型是Task<string>
。您正在尝试返回一个string
. 它们不相同,也没有从 string 到 的隐式转换Task<string>
,因此出现错误。
You're likely confusing this with an async
method in which the return value is automatically wrapped in a Task
by the compiler. Currently that method is not an async method. You almost certainly meant to do this:
您可能会将其与编译器async
自动将返回值包装在 a 中的方法混淆Task
。目前该方法不是异步方法。您几乎肯定打算这样做:
private async Task<string> methodAsync()
{
await Task.Delay(10000);
return "Hello";
}
There are two key changes. First, the method is marked as async
, which means the return type is wrapped in a Task
, making the method compile. Next, we don't want to do a blocking wait. As a general rule, when using the await
model always avoid blocking waits when you can. Task.Delay
is a task that will be completed after the specified number of milliseconds. By await
-ing that task we are effectively performing a non-blocking wait for that time (in actuality the remainder of the method is a continuation of that task).
有两个关键变化。首先,该方法被标记为async
,这意味着返回类型包含在 a 中Task
,使该方法可以编译。接下来,我们不想进行阻塞等待。作为一般规则,在使用await
模型时总是尽可能避免阻塞等待。 Task.Delay
是将在指定的毫秒数后完成的任务。通过await
-ing 该任务,我们有效地执行了该时间的非阻塞等待(实际上,该方法的其余部分是该任务的延续)。
If you prefer a 4.0 way of doing it, without using await
, you can do this:
如果您更喜欢 4.0 的方式,而不使用await
,您可以这样做:
private Task<string> methodAsync()
{
return Task.Delay(10000)
.ContinueWith(t => "Hello");
}
The first version will compile down to something that is more or less like this, but it will have some extra boilerplate code in their for supporting error handling and other functionality of await
we aren't leveraging here.
第一个版本将编译成或多或少类似的东西,但它会有一些额外的样板代码,用于支持错误处理和await
我们在这里没有利用的其他功能。
If your Thread.Sleep(10000)
is really meant to just be a placeholder for some long running method, as opposed to just a way of waiting for a while, then you'll need to ensure that the work is done in another thread, instead of the current context. The easiest way of doing that is through Task.Run
:
如果您Thread.Sleep(10000)
真的只是作为某个长时间运行的方法的占位符,而不是等待一段时间的方式,那么您需要确保工作在另一个线程中完成,而不是在当前上下文中完成。最简单的方法是通过Task.Run
:
private Task<string> methodAsync()
{
return Task.Run(()=>
{
SomeLongRunningMethod();
return "Hello";
});
}
Or more likely:
或者更有可能:
private Task<string> methodAsync()
{
return Task.Run(()=>
{
return SomeLongRunningMethodThatReturnsAString();
});
}
回答by user2388853
Beyond the problematic use of async
as pointed out by @Servy, the other issue is that you need to explicitly get T
from Task<T>
by calling Task.Result. Note that the Result property will block async code, and should be used carefully.
除了有问题的使用async
由@Servy如指出,另一个问题是,你需要明确地得到T
从Task<T>
调用Task.Result。请注意,Result 属性将阻止异步代码,应谨慎使用。
Try:
尝试:
private async void button1_Click(object sender, EventArgs e)
{
var s = await methodAsync();
MessageBox.Show(s.Result);
}
回答by Jaswant Agarwal
Use FromResult Method
使用 FromResult 方法
public async Task<string> GetString()
{
System.Threading.Thread.Sleep(5000);
return await Task.FromResult("Hello");
}
回答by Karteek Rakshit
//source
public async Task<string> methodName()
{
return Data;
}
//Consumption
methodName().Result;
Hope this helps :)
希望这可以帮助 :)