简体   繁体   English

C#.Net - 如何取消从WebService中提取数据的BackgroundWorker

[英]C#.Net - How to cancel a BackgroundWorker pulling data from a WebService

I've got the following code: 我有以下代码:

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

The code is basically calling a delegate to a WebService method. 代码基本上是调用WebService方法的委托。 Unfortunately, the main reason I used a background worker was to stop the UI freezing when loading the data. 不幸的是,我使用后台工作程序的主要原因是在加载数据时停止UI冻结。 I've got a form that pops up saying please wait, click here to cancel. 我有一个弹出的表格,请等待,点击这里取消。

On the click of cancel I call CancelAsync on the background worker. 点击取消后,我在后台工作人员上调用CancelAsync。 Now, as I'm not looping I cannot see a nice way of checking for a cancellation. 现在,由于我没有循环,我看不到检查取消的方法。 The only option I can see is to have... 我能看到的唯一选择是......

byte[] m_CurrentData;

...outside of the method and launch a new thread on the start of DoWork(..) that calls the webservice to populate m_CurrentData. ...在方法之外,在DoWork(..)的启动时启动一个新线程,调用webservice来填充m_CurrentData。 I'd then need to perform a loop checking if cancelled or checking if m_CurrentData is no longer null. 然后,我需要执行循环检查,如果取消或检查m_CurrentData是否不再为null。

Is there any better way of achieving a cancellation? 有没有更好的取消方式?

The actual work seems to be done inside the this.GetData(...) method which is not shown. 实际工作似乎是在this.GetData(...)方法中完成的,未显示。 I gather it is calling a webservice. 我知道它正在调用web服务。 You probably should call the Abort() method on the proxy object to stop the client from waiting for the response. 您可能应该调用代理对象上的Abort()方法来阻止客户端等待响应。 There is no point in calling CancelAsync() , just be sure to correctly check for errors in RunWorkerCompleted() . 调用CancelAsync()没有意义,只需确保在RunWorkerCompleted()正确检查错误。 The easiest way is probably not to catch any exceptions in _DoWork() , but check the Result.Error property in Completed() . 最简单的方法可能是捕获_DoWork()任何异常,但检查Completed()的Result.Error属性。 You should do that anyway. 无论如何你应该这样做。

Just to clarify, the CancelAsync() method is only useful to stop a loop inside DoWork(). 只是为了澄清,CancelAsync()方法仅用于在DoWork()内部停止循环。 You are not running a (meaningful) loop there, so another approach is needed. 你没有在那里运行(有意义的)循环,因此需要另一种方法。

Update 更新

I've just checked the MSDN for DoWorkEventArgs and realised that my previous answer was wrong. 我刚刚检查了MSDN for DoWorkEventArgs并意识到我以前的答案是错误的。 There's the CancellationPending property on the BackgroundWorker which is set by by the call to CancelAsync ( from the MSDN ). BackgroundWorker上有CancellationPending属性,它由对CancelAsync来自MSDN )的调用设置。 Thus your DoWork method can become: 因此,您的DoWork方法可以变为:

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

Can you use this? 你能用这个吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM