Каков наилучший способ для 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
Ваша идея должна работать нормально. В принципе, вы просто хотите создать кучу нитей и убедитесь, что те, кто пишет файл, занимают достаточно много времени, чтобы сделать это, чтобы заставить читателей ждать. Если все ваши потоки возвращаются без ошибок и без блокировки навсегда, то тест будет успешным.