使用BackgroundWorker从列表中检索最后选定项目的详细信息

发布于 2024-12-17 05:34:50 字数 304 浏览 0 评论 0原文

在我的应用程序中,我有一个从数据库填充的 DataGrid。当我单击其中一项时,会检索其详细信息并将其传递到 UI。获取项目详细信息是一项昂贵的操作,因此我使用BackgroundWorker 来处理它。当我在检索过程中选择另一个项目时,我想中止当前操作并使用新的项目 ID 开始另一个操作。最好的方法是什么?我尝试将其放入 DataGrid CellContentClick 处理程序中:

if(worker.IsBusy)
{
    worker.CancelAsync();
}

但我总是获得第一个选定项目的详细信息。

In my application I have a DataGrid that is populated from a database. When I click one of the items, its details are retrieved and passed to UI. Getting item details is a coslty operation so I use a BackgroundWorker to handle it. When I select another item during the retrieval, I would like to abort current operation and start another one using new item id. What;s the best way to do it? I tried to put this in DataGrid CellContentClick hanlder:

if(worker.IsBusy)
{
    worker.CancelAsync();
}

but I always get details of first selected item.

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

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

发布评论

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

评论(2

乙白 2024-12-24 05:34:50

听起来您没有检查 BackgroundWorker.CancellationPending

您必须执行以下操作:

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        // Do not access the form's BackgroundWorker reference directly.
        // Instead, use the reference provided by the sender parameter.
        BackgroundWorker bw = sender as BackgroundWorker;

        // Extract the argument.
        int arg = (int)e.Argument;

        // Start the time-consuming operation.
        e.Result = TimeConsumingOperation(bw, arg);

        // If the operation was canceled by the user, 
        // set the DoWorkEventArgs.Cancel property to true.
        if (bw.CancellationPending)
        {
            e.Cancel = true;
        }
    }

另请参阅如何:在背景

您可能希望在异步代码中对 CancellationPending 进行多次检查,在每个需要大量时间的步骤之后进行一次检查。

Sounds like you don't check for the BackgroundWorker.CancellationPending while retrieving the item data.

You will have to do something like this:

    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        // Do not access the form's BackgroundWorker reference directly.
        // Instead, use the reference provided by the sender parameter.
        BackgroundWorker bw = sender as BackgroundWorker;

        // Extract the argument.
        int arg = (int)e.Argument;

        // Start the time-consuming operation.
        e.Result = TimeConsumingOperation(bw, arg);

        // If the operation was canceled by the user, 
        // set the DoWorkEventArgs.Cancel property to true.
        if (bw.CancellationPending)
        {
            e.Cancel = true;
        }
    }

See also How to: Run an Operation in the Background.

Probably you want to place several checks for CancellationPending in your async code, one after each step that takes a significant amount of time.

林空鹿饮溪 2024-12-24 05:34:50

好吧,我自己想出来了。首先,我将以下块分散在整个worker_DoWork处理程序中:

if(worker.CancellationPending)
{
    e.Cancel = true;
    return;
}

当worker.CancellationPending为true时,我还阻止了worker.RunWorkerAsync()的执行。为了实现我的目标,我将以下代码添加到我的 RunWorkerCompleted 处理程序中:

if(!e.Cancelled)
{
    //update UI
}
else
{
    //retrieve details of new item
}

Ok, I figured it out myself. Firstly i scattered following blocks all over worker_DoWork handler:

if(worker.CancellationPending)
{
    e.Cancel = true;
    return;
}

I also prevented execution of worker.RunWorkerAsync(), when worker.CancellationPending is true. To achieve my goal I added the following code to my RunWorkerCompleted handler:

if(!e.Cancelled)
{
    //update UI
}
else
{
    //retrieve details of new item
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文