私は新しい非同期CTPの要素を手に入れようとしているので、おそらくここで混乱しています。この「タスクメソッド」を問題なく使用できます。
public static Task<String> LongTaskAAsync() {
return Task.Run(() => {
return("AAA");
});
}
しかし、別のタスクを実行するためにタスクが必要な場合は、それを「非同期」としてマークして「待機」を使用できますか?私はこれを試しました:
public async static Task<String> LongTaskAAsync() {
await Task.Delay(2000);
return Task.Run(() => {
return("AAA");
});
}
しかし、不思議なことにこのコンパイラエラーが発生します。これは非同期メソッドであるため、戻り式はTask<string>
ではなく 'string'型である必要があります
ここで何が欠けていますか?
私の async
/await
intro post を読むことをお勧めします。
async
メソッドからの戻り値はTask<TResult>
にラップされます。同様に、await
はこれらの戻り値のラップを解除します。
public static async Task<String> LongTaskAAsync() {
await Task.Delay(2000);
return await Task.Run(() => {
return("AAA");
});
}
これの背後にある理由は、私の (非同期 "キーワードが機能する理由ThatWay"非公式FAQ )で説明されています。
追伸このような簡単なテストにはTask.FromResult
を使用することもできます。
Edit:Task
オブジェクト自体を作成して返したい場合、メソッドはnotasync
になります。やや一般的なパターンの1つは、必要な場合にのみpublic
部分を呼び出すasync
non _async
メソッドを使用することです。
たとえば、ある種の非同期キャッシュ-オブジェクトがキャッシュにある場合は、すぐに返します。それ以外の場合は、非同期で作成してキャッシュに追加し、それを返します(これはサンプルコードです-スレッドセーフではありません)。
public static Task<MyClass> GetAsync(int key)
{
if (cache.Contains(key))
return Task.FromResult(cache[key]);
return CreateAndAddAsync(key);
}
private static async Task<MyClass> CreateAndAddAsync(int key)
{
var result = await CreateAsync(key);
cache.Add(key, result);
return result;
}
「タスクメソッド」を「非同期」メソッドにすることもできますか?
はい、可能です。メソッドのシグネチャをpublic async static Task<Task<String>> LongTaskAAsync()
に変更するだけです。つまり、それが返すものだからです。
async
キーワードを使用する場合、ランタイムは、非同期性を有効にするために、返される型をタスクにラップします。たとえば、string
を返す場合、ランタイムはそれをTask<string>
にラップします。 int
はTask<int>
に、Task<string>
はTask<Task<string>>
に行きます。明確にするために、このコンソールアプリを参照してください。
public class Program
{
public static void Main(string[] args)
{
// start the main procedure asynchron
Task.Run(() => DoIt()).Wait();
}
// for async support since the static main method can't be async
public static async void DoIt()
{
Program p = new Program();
// use the methods
string s = await p.GetString();
int i = await p.GetInt();
Task<string> tsk = await p.GetTaskOfString();
// just to prove the task works:
// C# 5
string resultFromReturnedTask = await tsk;
// C# 4
string resultFromReturnedTask2 = tsk.Result;
}
public async Task<string> GetString()
{
return "string";
}
public async Task<int> GetInt()
{
return 6;
}
public async Task<Task<string>> GetTaskOfString()
{
return Task.Run(() => "string");
}
}