0

次の簡単なコードを検討してください。それから質問します。

public static void Save(XmlDocument saveBundle)
    {
        ThreadStart threadStart = delegate
        {
            SaveToDatabase(saveBundle);
        };

        new Thread(threadStart).Start();            
    }

Visual Studio (2005) でスレッドを使用する際の問題は、それらを簡単にウォークスルーできないことです (もっと簡単な方法があることを望んでいるので、調べていないスレッドを切り替える方法があると思います)。

したがって、ライブでは、私のコードは上記の例よりも複雑であり、時間が重要であるため新しいスレッドを使用しますが、プリンシパルは同じです。最も重要なことは、テストではタイム クリティカルではないということです。

現時点では、おそらく を使用するようなことをするでしょうが、そうするの#if debugは間違っていると感じています - ここで #if を正しい方法で使用していますか、それともこれを解決するためのより良い方法はありますか?

public static void Save(XmlDocument saveBundle)
    {

   #if debug
      {
        SaveToDatabase(parameters);
        }
   #else
        {
            ThreadStart threadStart = delegate
            {
                SaveToDatabase(parameters);
            };

            new Thread(threadStart).Start();
        }
   #endif
      }
    }

私は .NET 2.0 で立ち往生していますが、.NET 20 以降のどのバージョンにも興味があります (いつかジュラ紀を離れて、他のすべての人に加わる日が来ると確信しています)。

4

3 に答える 3

2

元のコードには重要な機能が欠けていると思います。操作が完了した (または失敗した) ときに報告する何らかのメカニズム:

public static void Save(XmlDocument saveBundle, Action<Exception> completedCallback)
{
    ThreadStart threadStart = delegate
    {
        try
        {            
            SaveToDatabase(saveBundle);
            completedCallback(null);
        }
        catch (Exception ex)
        {
            completedCallback(ex);
        }
    };

    new Thread(threadStart).Start();            
}

そうすれば、ある種の同期方法を使用して単体テストを調整できます。

Exception actualException = null;
using (AutoResetEvent waitHandle = new AutoResetEvent(false))
{

    instance.Save(xmlDocument, ex =>
    {
        actualException = ex;
        waitHandle.Set();
    });
    waitHandle.WaitOne();
}

Assert.IsNull(actualException);
于 2012-12-14T08:59:16.537 に答える
1

本当にやりたいことがデバッグ ビルドでスレッド化を使用しない場合 - これが正しい方法であり、おそらく最も迅速で最も有能な方法でもあります。少し見苦しく見えるかもしれませんが、代替手段はブール値、構成、およびその他の回避策です。

スレッドを直接デバッグすることに興味がある場合 (同時実行性が問題になる場合、これはおそらく重要です! 常に本番環境にできるだけ近い場所でテストする必要があります)、単純に (デバッグ -> Windows -> スレッド) に移動してから、デバッグしたいスレッドを右クリックし、「スレッドに切り替え」ます。

于 2012-12-14T08:59:59.220 に答える
0

おそらく、このスレッド化コードを別のメソッドに入れ、テスト時にそのメソッドを置き換えることができます。

virtual void SaveToDBInSeparateThread(...)
{
    ThreadStart threadStart = delegate
    {
        ...
    };

    new Thread(threadStart).Start();  
}

void を返す代わりに、スレッドの実行などを返すことができます。

または、以下のようにメソッドに入力パラメーターを追加できます。

virtual void SaveToDB(bool inSeparateThread)
{
    if(inSeparateThread)
    {
      ThreadStart threadStart = delegate
      {
        ...
      };

      new Thread(threadStart).Start();  
    }
    ...
}

または、ある種の DatabaseSavingContext を提供できます。

interface IDBSaveContext
{
    public void SaveToDB(...)
}

また、実行タイプに応じて、このインターフェースの異なる実装 (スレッド化、非スレッド化) を使用します。

于 2012-12-14T09:06:32.560 に答える