2015-12-21 39 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

当然明白了。 –