2015-12-21 40 views
-1

我想實現一個線程安全的文件IO類。我知道這可以通過鎖和信號量來實現。但我想使用Rx,因爲我正在學習使用Rx。任何人都可以幫助我以線程安全的方式使用Rx實現以下IO操作合同。我有幾個想法,比如創建像創建外部請求保存或讀取文件的管道,按順序調度所有請求。但我在如何實施方面苦苦掙扎。請指導。使用Rx執行IO操作Threadsafe

public interface IFileIO 
    { 
     /// <summary> 
     /// Task which writes text to the file asynchronously 
     /// </summary> 
     Task WriteTextAsync(IsolatedStorageFileStream storageFile, string text); 

     /// <summary> 
     /// Task which reads text from the file asynchronously 
     /// </summary> 
     Task<string> ReadTextAsync(IsolatedStorageFileStream storageFile); 
    } 
+0

請詳細說明我是否嘗試做錯事。我的目標是學習如果我可以避免在這些場景中使用鎖。這可以幫助我避免諸如死鎖等鎖定機制的問題。 –

+0

使用Rx代替TPL是很好的,只需要注意Rx具有「零個或多個」值的語義,而TPL是「一個且只有一個值」。因此,任何返回一個值的東西肯定可以通過返回零或更多的東西來建模。 – Enigmativity

回答

0

我不知道如果我錯過了一些重要的東西,但你的界面應該是這樣的:

public interface IFileIO 
{ 
    IObservable<Unit> WriteTextAsync(IsolatedStorageFileStream storageFile, string text); 
    IObservable<string> ReadTextAsync(IsolatedStorageFileStream storageFile); 
} 

你會那麼實現這個使用System.Reactive.Concurrency.EventLoopScheduler來執行所有的調度實施。這將確保所有操作都在單個線程上執行。真的超級簡單。

Unit類型在接口是System.Reactive.Unit並且被用作一種類型以指示void(或不Task一個通用型)。您應始終使用System.Reactive.Unit.Default來獲得Unit的相同實例。

+0

謝謝@Enigmativity的答案。我得到了「唯一一個值」的任務語義和Rx是「零個或更多」模型的觀點。但是在Task中有沒有辦法避免使用鎖,信號量和實現IO庫線程安全。另外,我可以使這個資源基本這樣,如果多個線程試圖更新單個文件,那麼只有它應該管道有請求,否則它可以並行執行,如果文件不同。 –

+1

@BalrajSingh - 使用'EventLoopScheduler'將確保線程安全,因爲它只允許一個observable一次運行。不需要鎖或信號燈。單獨的文件管道有點麻煩,因爲我可以命名文件,如「C:\ Foo \ .. \ Bar.txt」或「C:\ Bar.txt」,我會指向相同的文件。您可能最好爲每個文件創建一個「工作單元」對象,但只有在協調文件訪問時纔有效。 – Enigmativity

+0

當然明白了。 –