複数のスレッドで同時に実行できないメソッドがあります (ファイルに書き込みます)。lock
メソッドが であるため、使用できませんasync
。別のスレッドでメソッドを呼び出さないようにするには? 2 回目に呼び出す代わりに、プログラムは前の呼び出しが完了するまで待機する必要があります (これも非同期で)。
たとえば、次のコードを使用して新しい C# コンソール アプリケーションを作成します。
using System;
using System.IO;
using System.Threading.Tasks;
namespace ConsoleApplication1 {
internal class Program {
private static void Main () {
CallSlowStuff();
CallSlowStuff();
Console.ReadKey();
}
private static async void CallSlowStuff () {
try {
await DoSlowStuff();
Console.WriteLine("Done!");
}
catch (Exception e) {
Console.WriteLine(e.Message);
}
}
private static async Task DoSlowStuff () {
using (File.Open("_", FileMode.Create, FileAccess.Write, FileShare.None)) {
for (int i = 0; i < 10; i++) {
await Task.Factory.StartNew(Console.WriteLine, i);
await Task.Delay(100);
}
}
}
}
}
この例では、2 番目の呼び出しCallSlowStuff
で例外がスローされます。これは、既に開かれているファイルにアクセスできないためです。混合しないため、追加lock
はオプションではlock
ありません。async
(Main
メソッドは変更不可と見なされるべきです。実際のアプリケーションでCallSlowStuff
は、どこでも呼び出すことができるインターフェイス メソッドです。)
質問:CallSlowStuff
メイン スレッドをブロックせずに、現在実行中の呼び出しが完了するまで待機する後続の呼び出しを行うにはどうすればよいですか? async/await とタスク (およびおそらく Rx) だけを使用して実行できますか?