无法隐式地将类型“ string”转换为“ System.Threading.Tasks. Task < string >”

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

我创建了一个简单的 Winformation 应用程序,并在表单中编写了以下代码

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);
}

有没有人能把灯放在这里。

216169 次浏览

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.

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:

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).

If you prefer a 4.0 way of doing it, without using await , you can do this:

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.

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:

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

Or more likely:

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

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.

Try:

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

Use FromResult Method

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;

Hope this helps :)

In my case.

        string ip = _GetStoreIpaddress().Result;




private async Task<string> _GetStoreIpaddress()
{
string _store_iP = "";
var Ip_address = await App.SQLiteDb.GetItemsAsync();
if (Ip_address != null)
{
_store_iP = Ip_address.ToString();
}


return _store_iP;
}