Это мой первый вопрос стека, поэтому заранее прошу прощения, если мой формат или этикет немного не в порядке.
Недавно я настраивал шаблоны для обработки «недопустимая операция между потоками» выдает при взаимодействии с элементами управления WinForms из отдельного потока.
Я подумал, что было бы неплохо настроить модульный тест, чтобы изолировать это, и утверждать, что мои расширения SynchronisationContext устранили проблему, поэтому я создал простую форму тестирования с одной кнопкой на ней и некоторым кодом, который называется PerformClick () из другого потока, чтобы повторить проблему:
[STAThread]
static void Main()
{
using (TestForm form = new TestForm())
{
Thread t1 = new Thread(() => Application.Run(form));
Thread t2 = new Thread(() => form.buttonStart.PerformClick());
form.Activated += (sender, args) => t2.Start();
t1.Start();
Thread.Sleep(1000); //Prevents form from being disposed before 'click' can occur from other thread.
}
}
Тестовая форма - это буквально пустая форма с одной кнопкой на ней. Когда я запустил этот код, я получил ожидаемое исключение операции между потоками.
Но когда я помещаю код в тест NUnit, исключение не возникает. Вот мой юнит тест:
[Test]
public void PostToControl_AcrossThreads()
{
//Notes: This code normally generates a cross-thread exception.
//For some reason, when you run it in the scope of the unit test, the exception is not generated.
using (TestForm form = new TestForm())
{
Thread t1 = new Thread(() => Application.Run(form));
Thread t2 = new Thread(() => form.buttonStart.PerformClick());
form.Activated += (sender, args) => t2.Start();
t1.Start();
Thread.Sleep(1000); //Prevents form from being disposed before 'click' can occur from other thread.
}
}
Я понял, что понятия не имею, почему это произойдет, поэтому я бросаю это экспертам :-)
Может ли кто-нибудь просветить меня? Что происходит в модульном тесте по-другому, по сравнению с собственным запуском формы?