Каков наилучший способ для unit test из нескольких потоков?

этот вид следует из другого question моего.

В принципе, как только у меня появится код для доступа к файлу (просмотрите ответы там через минуту), какой был бы лучший способ проверить его?

Я собираюсь создать метод, который просто порождает много BackgroundWorker или что-то еще и сообщает им, что все загружают/сохраняют файл, и тест с различными размерами файлов/объектов. Затем получите ответ от потоков, чтобы узнать, не сработал ли он/преуспел/сделал мир взорванным и т.д.

Можете ли вы, ребята, предложить какие-либо предложения по наилучшему подходу к этому? Как я уже говорил, это все для меня новичок:)

Изменить

Следующее сообщение ajmastrean:

Я использую консольное приложение для тестирования с помощью Debug.Asserts:)


Update

Я изначально катался с помощью BackgroundWorker, чтобы справиться с потоковой обработкой (поскольку я привык к тому, что от Windows dev), я скоро понял что, когда я выполнял тесты, где нужно было выполнить несколько операций (потоков), прежде чем продолжить, я понял, что это будет немного взломать, чтобы заставить это сделать.

Затем я продолжил публикацию ajmastrean и понял, что я действительно должен использовать Thread для работы с параллельными операциями. Теперь я буду использовать рефакторинг, используя этот метод (хотя и другой подход).

Ответ 1

В .NET потоки ThreadPool не возвращаются без настройки ManualResetEvent или AutoResetEvent s. Я нахожу эти излишества для быстрого метода тестирования (не говоря уже о том, что сложно создавать, устанавливать и управлять). Фоновый работник также немного сложнее с обратными вызовами и т.д.

Что-то я нашел, что работает

  • Создайте массив потоков.
  • Установите метод ThreadStart для каждого потока.
  • Начать каждый поток.
  • Присоединяйся ко всем потокам (блокирует текущий поток до тех пор, пока все остальные потоки не закончатся или не прервутся)
public static void MultiThreadedTest()
{
    Thread[] threads = new Thread[count];

    for (int i = 0; i < threads.Length; i++)
    {
        threads[i] = new Thread(DoSomeWork());
    }

    foreach(Thread thread in threads)
    {
        thread.Start();
    }

    foreach(Thread thread in threads)
    {
        thread.Join();
    }
}

Ответ 2

@ajmastrean, так как результат unit test должен быть предсказуемым, нам нужно как-то синхронизировать потоки. Я не вижу простой способ сделать это, не используя события.

Я обнаружил, что ThreadPool.QueueUserWorkItem дает мне простой способ проверить такие варианты использования

 ThreadPool.QueueUserWorkItem(x => { 
    File.Open(fileName, FileMode.Open);
    event1.Set(); // Start 2nd tread;
    event2.WaitOne(); // Blocking the file;
});
ThreadPool.QueueUserWorkItem(x => { 
    try
    {
        event1.WaitOne(); // Waiting until 1st thread open file
        File.Delete(fileName); // Simulating conflict
    }
    catch (IOException e)
    {
        Debug.Write("File access denied");
    }
});

Ответ 3

Ваша идея должна работать нормально. В принципе, вы просто хотите создать кучу нитей и убедитесь, что те, кто пишет файл, занимают достаточно много времени, чтобы сделать это, чтобы заставить читателей ждать. Если все ваши потоки возвращаются без ошибок и без блокировки навсегда, то тест будет успешным.