BackgroundWorker 不与 TeamCity NUnit 运行程序一起使用

发布于 2024-08-30 21:58:05 字数 1378 浏览 1 评论 0原文

我正在使用 NUnit 测试 WPF 3.5 应用程序中的视图模型,并使用 BackgroundWorker 类执行异步命令。单元测试在 NUnit 运行程序或 ReSharper 运行程序中运行良好,但失败TeamCity 5.1 服务器。

它是如何实现的:

我使用名为 IsBusyViewModel 属性,并在 BackgroundWorker.RunWorkerCompleted 事件上将其设置为 false。在我的测试中,我使用这种方法来等待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
...

怎么可能?!

I'm using NUnit to test View Models in a WPF 3.5 application and I'm using the BackgroundWorker class to execute asynchronous commands.The unit test are running fine with the NUnit runner or ReSharper runner but fail on TeamCity 5.1 server.

How is it implemented :

I'm using a ViewModel property named IsBusy and set it to false on BackgroundWorker.RunWorkerCompleted event. In my test I'm using this method to wait for the BackgroundWorker to finish :

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();
}

Well, sometimes it works and sometimes it hangs the build. I suppose it's the Application.DoEvents() but I don't know why...

Edit: I added some traces (see code above) and in the log I have :

WaitForBackgroundOperation 1 
WaitForBackgroundOperation 2 
WaitForBackgroundOperation 2 
WaitForBackgroundOperation 2
...

How is it possible ?!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

仅冇旳回忆 2024-09-06 21:58:05

您正在启动一堆后台任务,每秒一个。将 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。

You are launching a bunch of background tasks, one per second. Move the RunBackgroundWorker above the loop.

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 { }));
}

The DoEvents should not be needed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文