2013-07-01 34 views
9

Harici bir uygulama tarafından oluşturulacak bir dosya için await'un en temiz yolu hangisi olurdu?Async dosya oluşturulmasını bekliyor

await Task.Run(() => {while(!File.Exists(@"yourpath.extension")){} return;}); 
//do all the processing 

Ayrıca bir yönteme içine paket olabilir:

public static Task WaitForFileAsync(string path) 
{ 
    if (File.Exists(path)) return Task.FromResult<object>(null); 
    var tcs = new TaskCompletionSource<object>(); 
    FileSystemWatcher watcher = new FileSystemWatcher(Path.GetDirectoryName(path)); 
    watcher.Created += (s, e) => 
    { 
     if (e.FullPath.Equals(path)) 
     { 
      tcs.TrySetResult(null); 
      if (watcher != null) 
      { 
       watcher.EnableRaisingEvents = false; 
       watcher.Dispose(); 
      } 
     } 
    }; 
    watcher.Renamed += (s, e) => 
    { 
     if (e.FullPath.Equals(path)) 
     { 
      tcs.TrySetResult(null); 
      if (watcher != null) 
      { 
       watcher.EnableRaisingEvents = false; 
       watcher.Dispose(); 
      } 
     } 
    }; 
    watcher.EnableRaisingEvents = true; 
    return tcs.Task; 
} 

ve sonra sadece bu gibi kullanabilirsiniz:

async Task doSomethingWithFile(string filepath) 
    { 
     // 1. await for path exists 
     // 2. Do something with file 
    } 

cevap

12

İlk anahtar nokta, bir Bir dosya sistemi olayı belirli bir yolda değiştiğinde bildirim almak için FileSystemWatcher. Örneğin, belirli bir yerde bir dosya oluşturulduğunda bilgilendirilmek istiyorsanız bunu öğrenebilirsiniz.

Daha sonra, dosya sistemi izleyicisi ilgili olayı tetiklediğinde, bir görevin tamamlanması için TaskCompletionSource kullanan bir yöntem oluşturabiliriz. Bu ilk önce, eğer varsa, hemen çıkmasına izin vermek için dosyanın mevcut olup olmadığını kontrol edeceğini unutmayın. Ayrıca, hem oluşturulmuş hem de yeniden adlandırılan işleyicilerin her ikisini de kullanır; bu seçenek, dosyanın gelecekte bir noktada var olmasını sağlayabilir. FileSystemWatcher da yalnızca dizinleri izler, bu nedenle belirtilen yolun dizinini almak ve ardından olay işleyicisindeki her etkilenen dosyanın dosya adını kontrol etmek önemlidir.

Ayrıca, kod tamamlandığında etkinlik işleyicilerini kaldırdığını unutmayın.

Bu bize yazmak için izin verir: Yoğun-bekleyen için

public static async Task Foo() 
{ 
    await WhenFileCreated(@"C:\Temp\test.txt"); 
    Console.WriteLine("It's aliiiiiive!!!"); 
} 
+0

Yol zaten mevcutsa WhenFileCreated tamamlanacak mı? –

+0

@AlexS Hayır. Yalnızca bir satır kodla bu durumu işlemek için yöntemin başlangıcında bunu kontrol edebilirsiniz. – Servy

+1

Dosya adı düzenlenmişse ne olur? Ayrıca, belirli bir dosya adı için beklemek istiyor. –

-4

Bu

yapardım nasıl
await WaitForFileAsync("yourpath.extension"); 
//do all the processing 
+4

-1. –

+0

@StephenCleary Peki, bir FileExistsAsync yok mu? 'FileSystemWatcher' size yanlış yol adını verebilir ve her zaman yeniden adlandırmayı ya da dosya mevcut değilse. Bu muhtemelen en iyi yoldur. –

+0

@StephenCleary Anyways, düzeltmeyi başardı. –