0

我正在用 C# (.net 3.5) 编写一个应用程序,我有一个关于类设计的问题:

我想创建一个访问文件(读、写)并将其内容提供给该类的用户(实例化器)的类。实例上最常见的操作是从文件中检索某个值。实际的读写(io)操作非常昂贵,所以我想将文件数据保存在内存中并让所有实例访问这些数据。该类位于同时从各种应用程序中使用的程序集中,所以我想我应该担心线程安全。

关于线程安全和单元可测试性,我该如何设计(对于单元测试,必须使用与操作代码不同的输入文件)?任何帮助是极大的赞赏。

4

3 回答 3

1

首先,让你的类实现一个合适的接口。这样,客户就可以测试他们的行为,而不需要真正的文件。

测试线程安全性很困难——我从未见过在这方面真正有用的东西,尽管这并不是说这些工具不存在。

对于您的课程的单元测试,我建议如果可能的话,它应该使用通用流而不仅仅是文件。然后,您可以在测试程序集中嵌入不同的测试文件,并使用GetManifestResourceStream引用它们。我过去曾多次这样做,取得了巨大的成功。

于 2008-10-16T11:43:50.900 回答
1

使用ReaderWriterLock,我认为这符合问题描述。

以下是一个快速而肮脏的实现。获取锁可能更聪明,比如在救助之前尝试多次等。但你明白了:

public class MyFooBarClass
{
   private static ReaderWriterLock readerWriterLock = new ReaderWriterLock();
   private static MemoryStream fileMemoryStream;

   // other instance members here

   public void MyFooBarClass()
   {
     if(fileMemoryStream != null)
     {
        // probably expensive file read here
     }

     // initialize instance members here
   }

   public byte[] ReadBytes()
   {
    try
    {
        try
         {
            readerWriterLock.AcquireReaderLock(1000);
            //... read bytes here
            return bytesRead;
         }
         finally
         {
            readerWriterLock.ReleaseReaderLock();
         }
     }
     catch(System.ApplicationException ex)
     {
        System.Diagnostics.Debug.WriteLine(ex.Message);
     }
   }

   public void WriteBytes(bytes[] bytesToWrite)
   {
    try
    {
        try
         {
            readerWriterLock.AcquireWriterLock(1000);
            //... write bytes here
         }
         finally
         {
            readerWriterLock.ReleaseWriterLock();
         }
     }
     catch(System.ApplicationException ex)
     {
        System.Diagnostics.Debug.WriteLine(ex.Message);
     }
   }
}
于 2008-10-16T14:52:34.187 回答
0

关于线程安全:线程安全不是问题,除非单个应用程序中的多个线程同时引用您的类的同一个实例。除非您的类包含在进程外服务器中,否则多个应用程序无法同时引用同一个实例。因此,您可能会看到的冲突将来自文件共享违规而不是线程问题(换句话说,类的不同实例试图读取和写入同一个文件)。是的,您必须设计代码以适当地处理文件共享。

使类可单元测试的一种方法是在构造函数中为类提供流,而不是让类直接访问文件。然后单元测试可以提供内存流,例如,而不是提供文件流。

于 2008-10-16T12:16:44.187 回答