C# 无法隐式转换类型';字符串';至';System.Threading.Tasks.Task<;字符串>';

C# 无法隐式转换类型';字符串';至';System.Threading.Tasks.Task<;字符串>';,c#,task-parallel-library,async-await,C#,Task Parallel Library,Async Await,我是异步编程新手,所以在阅读了一些异步示例代码之后,我想到了编写一个简单的异步代码 我创建了一个简单的Winform应用程序,并在表单中编写了以下代码。但它只是不起作用 private Task<string> methodAsync() { Thread.Sleep(10000); return "Hello"; //Error: Cannot implicitly convert type 'string' to 'System.Threading.Tasks.T

我是异步编程新手,所以在阅读了一些异步示例代码之后,我想到了编写一个简单的异步代码

我创建了一个简单的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);
}
private Task methodAsync(){
睡眠(10000);
返回“Hello”;//错误:无法将类型“string”隐式转换为“System.Threading.Tasks.Task”
}
私有异步无效按钮1\u单击(对象发送方,事件参数e)
{
字符串s=await methodAsync();
MessageBox.Show(s);
}

有人能在这里放点灯吗?

列出的方法返回类型是
Task
。您试图返回一个
字符串
。它们不一样,也不存在从字符串到任务的隐式转换,因此出现错误

您可能会将其与
async
方法混淆,在该方法中,编译器会将返回值自动包装到
任务中。当前,该方法不是异步方法。你几乎肯定是有意这么做的:

private async Task<string> methodAsync() 
{
    await Task.Delay(10000);
    return "Hello";
}
第一个版本将编译成或多或少类似于这样的东西,但它将有一些额外的样板代码,用于支持错误处理和
wait
的其他功能,我们在这里没有利用这些功能

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

private Task<string> methodAsync() 
{
    return Task.Run(()=>
        {
            SomeLongRunningMethod();
            return "Hello";
        });
}
private Task methodAsync()
{
返回任务。运行(()=>
{
SomeLongRunningMethod();
回复“你好”;
});
}
或者更可能:

private Task<string> methodAsync() 
{
    return Task.Run(()=>
        {
            return SomeLongRunningMethodThatReturnsAString();
        });
}
private Task methodAsync()
{
返回任务。运行(()=>
{
返回返回字符串()的LongRunning方法;
});
}

除了@Servy指出的使用
async
有问题之外,另一个问题是您需要通过调用Task.Result从
Task
显式获取
T
。请注意,Result属性将阻止异步代码,应小心使用

尝试:

使用FromResult方法

public async Task<string> GetString()
{
   System.Threading.Thread.Sleep(5000);
   return await Task.FromResult("Hello");
}
公共异步任务GetString() { 系统线程线程睡眠(5000); 返回等待任务。FromResult(“Hello”); }
//来源
公共异步任务methodName()
{
返回数据;
}
//消耗
methodName().Result;

希望这有帮助:)

如何在
任务
中显式包装
字符串
?或者在被调用的方法(本例中为methodAsync)中没有使用
async
await
返回
Task
Task
的方法吗?@Aniket不,你错了,有很多方法可以在任务中显式包装字符串。我将在中编辑一个解决方案。@Servy:假设我没有使用延迟和其他一些代码,而这些代码在
methodAsync
中造成了相同的延迟,我应该如何通过将结果字符串包装到任务中来返回它?您可以使用Task.FromResult将字符串包装到任务中。@dotnebeginner,如果你不相信我,你可以自己试试<代码>等待
意味着,启动该任务,一旦它启动,向该任务添加一个延续,并在异步任务完成后继续使用我停止的方法。如果您只是在异步方法中使用
Sleep
,然后使用
Task.FromResult
,它将花费整整10秒钟来启动任务,直到任务完成后再返回调用方,这样就可以一直阻塞UI线程,并有效地同步运行整个过程。虽然这可能不是强烈推荐的做法,但有一个实例,我想在
catch{}
中获取
Task
内容。我无法
等待
,而
.ToString()
产生了不正确的结果。这正是我所需要的,其他答案都没有提供。据我所知,这个答案是用同步实现的任务定义接口的最佳方法
private async void button1_Click(object sender, EventArgs e)
{
    var s = await methodAsync();
    MessageBox.Show(s.Result);
}
public async Task<string> GetString()
{
   System.Threading.Thread.Sleep(5000);
   return await Task.FromResult("Hello");
}
    //source    
    public async Task<string> methodName()
            {
             return Data;
             }

    //Consumption
     methodName().Result;