BackgroundWorker не работает с TeamCity NUnit Runner - PullRequest
2 голосов
/ 29 апреля 2010

Я использую NUnit для тестирования моделей просмотра в приложении WPF 3.5 и использую класс BackgroundWorker для выполнения асинхронных команд. Модульное тестирование работает нормально с бегуном NUnit или бегом ReSharper, но не выполняется в TeamCity 5.1 сервер.

Как это реализовано:

Я использую свойство ViewModel с именем IsBusy и задаю для него значение false для события BackgroundWorker.RunWorkerCompleted. В моем тесте я использую этот метод для ожидания завершения BackgroundWorker:

protected void WaitForBackgroundOperation(ViewModel viewModel)
{
    Console.WriteLine("WaitForBackgroundOperation 1");
    int count = 0;
    while (viewModel.IsBusy)
    {
        Console.WriteLine("WaitForBackgroundOperation 2");
        RunBackgroundWorker();
        Console.WriteLine("WaitForBackgroundOperation 3");

        if (count++ >= 100)
        {
            Assert.Fail("Background operation too long");
        }
        Thread.Sleep(1000);

        Console.WriteLine("WaitForBackgroundOperation 4");
    }
}

private static void RunBackgroundWorker()
{
    Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate { }));
    System.Windows.Forms.Application.DoEvents();
}

Ну, иногда это работает, а иногда зависает сборка. Я полагаю, это Application.DoEvents(), но я не знаю почему ...

Редактировать: Я добавил несколько следов (см. Код выше) и в журнале у меня есть:

WaitForBackgroundOperation 1 
WaitForBackgroundOperation 2 
WaitForBackgroundOperation 2 
WaitForBackgroundOperation 2
...

Как это возможно?!

1 Ответ

0 голосов
/ 18 мая 2011

Вы запускаете кучу фоновых задач, по одной в секунду. Переместите RunBackgroundWorker над циклом.

protected void WaitForBackgroundOperation(ViewModel viewModel)
{
    Console.WriteLine("WaitForBackgroundOperation 1");
    RunBackgroundWorker();
    Thread.Sleep(100); // wait for thread to set isBusy, may not be needed
    int count = 0;
    while (viewModel.IsBusy)
    {
        Console.WriteLine("WaitForBackgroundOperation 2");
        if (count++ >= 100)
        {
            Assert.Fail("Background operation too long");
        }
        Thread.Sleep(1000);
        Console.WriteLine("WaitForBackgroundOperation 3");
    }
}

private static void RunBackgroundWorker()
{
    Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Background, new ThreadStart(delegate { }));
}

DoEvents не нужно.

...