0

C# (.net 3.5) でアプリを作成していますが、クラスの設計について質問があります。

ファイルにアクセス (読み取り、書き込み) し、そのコンテンツをクラスのユーザー (インスタンス作成者) に提供するクラスを作成したいと考えています。インスタンスに対する最も一般的な操作は、ファイルから特定の値を取得することです。実際の読み取りおよび書き込み (io) 操作は非常にコストがかかるため、ファイル データをメモリに保持し、すべてのインスタンスがこのデータにアクセスできるようにしたいと考えています。このクラスは、さまざまなアプリケーションから同時に使用されるアセンブリに配置されているため、スレッド セーフについて心配する必要があると思います。

スレッドセーフと単体テスト容易性に関してこれを設計するにはどうすればよいですか (単体テストの場合、運用コードとは異なる入力ファイルを使用する必要があります)。どんな助けでも大歓迎です。

4

3 に答える 3

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 に答える
1

まず、クラスに適切なインターフェースを実装させます。そうすれば、クライアントは実際のファイルをまったく必要とせずに動作をテストできます。

スレッドの安全性をテストするのは難しいです。ツールが存在しないというわけではありませんが、その面で本当に役立つものを見たことがありません。

クラスの単体テストについては、可能であれば、単なるファイルではなく一般的なストリームで動作することをお勧めします。次に、さまざまなテスト ファイルをテスト アセンブリに埋め込み、GetManifestResourceStreamでそれらを参照できます。私はこれを過去に数回行い、大きな成功を収めました。

于 2008-10-16T11:43:50.900 に答える
0

スレッドセーフについて:単一のアプリケーション内の複数のスレッドがクラスの同じインスタンスを同時に参照しない限り、スレッドセーフは問題になりません。クラスがアウトプロセスサーバー内に含まれていない限り、複数のアプリケーションが同じインスタンスを同時に参照する方法はありません。したがって、発生する可能性のある競合は、スレッドの問題(つまり、同じファイルの読み取りと書き込みを試みるクラスの異なるインスタンス)ではなく、ファイル共有違反が原因で発生します。はい、ファイル共有を適切に処理するようにコードを設計する必要があります。

クラスユニットをテスト可能にする1つの方法は、クラスにファイルに直接アクセスさせるのではなく、コンストラクターでクラスにストリームを提供することです。次に、単体テストは、たとえばファイルストリームを提供する代わりに、メモリストリームを提供できます。

于 2008-10-16T12:16:44.187 に答える