使用BackgroundWorker进行线程化

发布于 2024-07-26 21:28:01 字数 385 浏览 11 评论 0原文

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

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

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

请让我知道这个问题的解决方案...

I have a scenario. I have a list of user id's displayed on the windows form. As soon as I click one of the user id's I go and get the user details from the DB. To retain the responsiveness of the application, on selection changed event of the listbox, I create new BackgroundWorker(BW) objects and hit the DB. I show 'Searching user 'abc'...' in the status bar.

Now, if the user moves between the user ids using arrow keys (4-5 times), by above design I have created multiple BW objects to make the request. But finally when the data comes back for particular user (which may not be the one where user is currently selected in the listview), since it was async call, I still end up displaying all the users in the status bar.

What I would like to do is, I want to go and get the details only for the last user. Till that time I want to display 'Searching user...' only.

Please let me know solution for this...

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

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

发布评论

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

评论(4

云柯 2024-08-02 21:28:01

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

When the user switches users, you can cancel the worker processes that are currently running (check to make sure they are running). I believe that would accomplish what you are after.

孤寂小茶 2024-08-02 21:28:01

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

用户单击用户 ID 后,以 1 秒的间隔启动计时器,一秒后启动您的后台工作程序。 如果用户点击不同的用户 ID,则重置计时器。 这样,如果用户不断快速连续点击不同的用户 ID,您将不会执行任何操作。 一旦用户休息一下,您就启动后台工作人员。

How about waiting for a second or two before you start your Background Worker?

Once the user clicks on a user id, start a timer with 1 second interval and after that one second, start your BackgroundWorker. If user clicks on a different user id, reset the timer. This way, if user keeps clicking on different user ids in quick succession, you won't do anything. Once user has taken a break, you start your background worker.

空城旧梦 2024-08-02 21:28:01

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

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

或者,如果您保留对所有后台工作人员的引用,则可以使用他们的取消支持。

One option would be to keep a string field in the form containing the user ID. In the background worker, after you hit the DB, check that this field is still equal to the user ID that it got passed in, EDIT: and, if it's different, make the result null. Manipulate the field using the methods on the Interlocked class to avoid the need to lock. That's wrong; reference types can be read and written atomically with Interlocked.

2nd EDIT: You could also return the original user ID from the background worker along with the result, and check that it's the most recent one clicked in your Completed handler.

Alternatively, if you're keeping references to all of the BackgroundWorkers, you could use their cancellation support.

小梨窩很甜 2024-08-02 21:28:01

我之前用它来取消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 之类的东西,那么它们实际上可能会导致竞争条件。

I've used this to cancel BackgroundWorkers before and it worked great.

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

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

I've heard controversy over using Application.DoEvents(); but I had problems with endless loops if I used Thread.sleep or other.

You might want to use polling of some sort so you don't end up with backgroundWorkers fumbling over eachother - especially if the callback ends up calling something like the UI on a separate thread so they can actually cause race conditions.

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