1. ホーム
  2. c#

[解決済み] 暗黙のうちに型 'string' を 'System.Threading.Tasks.Task<string>' に変換できない

2023-05-01 14:21:56

質問

私は非同期プログラミングの初心者なので、いくつかの非同期サンプルコードを見て、簡単な非同期コードを書こうと思いました。

私は簡単な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);
}

誰かここに光を当ててください...

どのように解決するのですか?

メソッドのリストされた戻り値の型は Task<string> . を返そうとしています。 string . これらは同じではありませんし、文字列から暗黙のうちに Task<string> への暗黙の変換もないため、エラーになります。

と混同している可能性があります。 async メソッドで、返り値が自動的に Task で自動的にラップされます。 現在、そのメソッドは非同期メソッドではありません。 ほぼ間違いなくこれを意図しているはずです。

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

2つの重要な変更があります。 まず、このメソッドは async とマークされています。これは、戻り値の型が Task で包まれ、メソッドがコンパイルできるようになります。 次に、ブロッキング待ちをしないようにします。 一般的なルールとして await モデルを使うときは、できる限りブロック待ちを避けるようにしましょう。 Task.Delay は、指定されたミリ秒後に完了するタスクです。 によって await -を指定することで、その時間だけノンブロッキングで待機することになります(実際には、このメソッドの残りの部分はそのタスクの継続です)。

を使用しない 4.0 の方法を好むのであれば、このメソッドでは 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();
        });
}