0

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

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

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

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

4

4 回答 4

2

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

于 2009-07-15T17:57:57.723 回答
1

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

一旦用户点击一个用户 ID,启动一个以 1 秒为间隔的计时器,一秒后,启动您的 BackgroundWorker。如果用户单击不同的用户 ID,则重置计时器。这样,如果用户不断快速连续点击不同的用户 ID,您将不会做任何事情。用户休息后,您将启动后台工作程序。

于 2009-07-15T20:30:35.777 回答
0

一种选择是在包含用户 ID 的表单中保留一个字符串字段。在后台工作人员中,点击数据库后,检查该字段是否仍等于传入的用户 ID,编辑:如果不同,则生成结果null使用类上的方法操作字段Interlocked以避免需要锁定。 那是错误的;引用类型可以用Interlocked.

第二次编辑您还可以从后台工作人员返回原始用户 ID 以及结果,并检查它是否是您的 Completed 处理程序中最近单击的一个。

或者,如果您保留对所有 BackgroundWorker 的引用,则可以使用它们的取消支持。

于 2009-07-15T17:59:18.110 回答
-1

我以前用它来取消 BackgroundWorkers,效果很好。

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

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

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

您可能希望使用某种轮询,这样您就不会最终让 backgroundWorkers 互相摸索——尤其是如果回调最终在单独的线程上调用 UI 之类的东西,那么它们实际上会导致竞争条件。

于 2009-07-15T18:09:53.283 回答