2016-02-02 57 views
4

我有一個DataFlow與TransformBlock同時運行異步磁盤讀取方法。例如,從磁盤陣列中讀取幾個文件,以非單獨的讀取請求隊列深度提供性能優勢。當異步塊併發性不止一個時,拋出異常時會發生什麼?

直觀地說,當最後一個ActionBlock完成時,所有的管道工作都應該完成。但是,會發生以下情況:

假設Rabbit和Bear開始將兩個文件讀取到它們自己的字節緩衝區中。兔子拋出一個EatenByAWolf異常。 Bear稍後完成,因爲它的文件有點大。當熊從冬眠的冬眠中醒來時,EatenByAWolf異常似乎已傳播到最後一個ActionBlock的Completion wait-site。那麼,問題是我在這裏清理了Rabbit和Bear等字節緩衝區,導致Bear嗆到NullRefToBuffer異常。

推薦的方法是什麼?我是否還應該在清除緩衝區之前等待Reader塊(包含所有動物)完成,還是可以更優雅地處理?

Task.WaitAll(new[] { readerBlock.Completion, lastActionBlock.Completion }); 

lastActionBlock.Completion.Wait(); 

回答

1

我在抽象的錯誤級別管理字節的緩衝區。

對於我來說,解決方案是在創建執行多個異步讀取的TransformBlock時使用有狀態的讀取器對象。將ConcurrentBag<>的緩衝區添加到MyFileReaderWithCachingByteBuffers閱讀器對象中,可確保緩衝區不會清除,直到由閉包捕獲的閱讀器對象超出範圍。只有當所有讀操作完成時纔會發生這種情況

var fileReader = new MyFileReaderWithCachingByteBuffers(biggestFileSize); 
var readerBlock = new TransformBlock<string, MyObject>(
      animal => fileReader.ReadAsync(animal), 
      new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = customDOP }); 
相關問題