使用BackgroundWorker从列表中检索上次选择的项目的详细信息

时间:2011-11-21 09:48:49

标签: c# winforms multithreading backgroundworker

在我的应用程序中,我有一个从数据库填充的DataGrid。当我单击其中一个项目时,将检索其详细信息并将其传递给UI。获取项目详细信息是一项常见的操作,因此我使用BackgroundWorker来处理它。当我在检索期间选择另一个项目时,我想中止当前操作并使用新项目ID启动另一个项目。什么是最好的方法呢?我试着将它放在DataGrid CellContentClick hanlder:

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

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

2 个答案:

答案 0 :(得分:1)

听起来你在检索项目数据时没有检查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;
        }
    }

另见How to: Run an Operation in the Background

您可能希望在异步代码中对CancellationPending进行多次检查,每次执行一次需要花费大量时间。

答案 1 :(得分:1)

好的,我自己弄清楚了。首先,我分散了遍及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
}