3

我有以下代码:

void ReferenceManager_DoWork(object sender, DoWorkEventArgs e)
{
    try
    {

        // Get the raw data
        byte[] data = this.GetData(IvdSession.Instance.Company.Description, IvdSession.Instance.Company.Password);

        // Deserialize the list
        List<T> deseriaizedList = null;
        using (MemoryStream ms = new MemoryStream(data))
        {
            deseriaizedList = Serializer.Deserialize<List<T>>(ms);
        }

        // Convert the list to the Reference Interface
        List<IReference> referenceList = new List<IReference>();
        foreach (T entity in deseriaizedList)
        {
            IReference reference = (IReference)entity;
            referenceList.Add(reference);
        }

        e.Result = referenceList;

    }
    catch (WebException)
    {
        e.Result = null;
    }
}

该代码基本上是调用 WebService 方法的委托。不幸的是,我使用后台工作人员的主要原因是在加载数据时停止 UI 冻结。我有一个弹出的表格说请稍候,点击这里取消。

单击取消后,我在后台工作人员上调用 CancelAsync。现在,由于我没有循环播放,我看不到检查取消的好方法。我能看到的唯一选择是...

byte[] m_CurrentData;

...在方法之外并在 DoWork(..) 开始时启动一个新线程,该线程调用 Web 服务来填充 m_CurrentData。然后,我需要执行循环检查是否取消或检查 m_CurrentData 是否不再为空。

有没有更好的方法来实现取消?

4

2 回答 2

3

实际工作似乎是在this.GetData(...)未显示的方法内完成的。我收集它正在调用网络服务。您可能应该调用Abort()代理对象上的方法来阻止客户端等待响应。调用没有意义CancelAsync(),只要确保正确检查RunWorkerCompleted(). 最简单的方法可能是 捕获任何异常_DoWork(),而是检查 Result.Error 中的属性Completed()。无论如何你都应该这样做。

澄清一下,CancelAsync() 方法仅用于在 DoWork() 中停止循环。您没有在那里运行(有意义的)循环,因此需要另一种方法。

于 2009-06-09T19:46:52.627 回答
1

更新

我刚刚检查了MSDNDoWorkEventArgs并意识到我之前的答案是错误的。通过调用(来自 MSDN)来设置该CancellationPending属性。因此,您的方法可以变成:BackgroundWorkerCancelAsyncDoWork

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;
    }
}

你能用这个吗?

于 2009-06-09T19:34:17.787 回答