使用BackgroundWorker进行线程处理

时间:2009-07-15 17:54:30

标签: multithreading background backgroundworker worker

我有一个场景。我在Windows窗体上显示了一个用户ID列表。只要我点击其中一个用户ID,我就会从数据库中获取用户详细信息。为了保持应用程序的响应性,在列表框的选择更改事件上,我创建新的BackgroundWorker(BW)对象并点击数据库。我在状态栏中显示“正在搜索用户'abc'...'。

现在,如果用户使用箭头键(4-5次)在用户ID之间移动,通过上述设计,我创建了多个BW对象来发出请求。但最后当特定用户(可能不是列表视图中当前选择用户的那个)的数据回来时,由于它是异步调用,我仍然最终显示状态栏中的所有用户。

我想做的是,我想去获取最后一位用户的详细信息。直到那时我才想显示“搜索用户...”。

请让我知道解决方案...

4 个答案:

答案 0 :(得分:2)

当用户切换用户时,您可以取消当前正在运行的工作进程(检查以确保它们正在运行)。我相信这会实现你的目标。

答案 1 :(得分:1)

在启动后台工作程序之前等待一两秒怎么样?

用户点击用户ID后,启动一个间隔为1秒的计时器,然后在一秒钟后启动BackgroundWorker。如果用户单击其他用户ID,请重置计时器。这样,如果用户快速连续点击不同的用户ID,您将不会执行任何操作。一旦用户休息,你就开始你的后台工作。

答案 2 :(得分:0)

一种选择是在包含用户ID的表单中保留字符串字段。在后台工作程序中,在您点击数据库后,检查此字段是否仍然等于传入的用户ID,编辑:如果不同,则生成结果{{1} }。 使用Interlocked类上的方法操作字段以避免需要锁定。这是错误的;可以使用null以原子方式读取和写入引用类型。

2 nd 编辑:您还可以从后台工作人员返回原始用户ID以及结果,并检查它是否是您在已完成时单击的最新用户ID处理程序。

或者,如果你保留对所有BackgroundWorkers的引用,你可以使用他们的取消支持。

答案 3 :(得分:-1)

我之前用它取消了BackgroundWorkers并且效果很好。

    public void cancelWorker( BackgroundWorker worker )
    {
        if (worker != null)
        {
            if (worker.IsBusy)
            {
                worker.CancelAsync();

                while (worker.IsBusy)
                {
                    Application.DoEvents();
                }
            }
        }
    }

我听说过使用Application.DoEvents();但是如果我使用Thread.sleep或其他的话,我会遇到无限循环的问题。

你可能想要使用某种类型的轮询,这样你最终就不会遇到背景笨蛋 - 特别是如果回调最终在一个单独的线程上调用类似UI的东西,那么它们实际上可能会导致竞争条件。