C # .Net - Как отменить BackgroundWorker извлечения данных из веб-службы - PullRequest
3 голосов
/ 09 июня 2009

У меня есть следующий код:

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. К сожалению, основной причиной, по которой я использовал фоновый рабочий, было прекращение зависания пользовательского интерфейса при загрузке данных. У меня есть форма, которая говорит: «Пожалуйста, подождите, нажмите здесь, чтобы отменить.

При нажатии кнопки отмены я вызываю функцию CancelAsync в фоновом режиме. Теперь, когда я не зацикливаюсь, я не вижу хороший способ проверки отмены. Единственный вариант, который я вижу, это иметь ...

byte[] m_CurrentData;

... вне метода и запуска нового потока в начале DoWork (..), который вызывает веб-сервис для заполнения m_CurrentData. Затем мне нужно будет выполнить проверку цикла, если она отменена, или проверку, если m_CurrentData больше не равен нулю.

Есть ли лучший способ добиться отмены?

Ответы [ 2 ]

3 голосов
/ 09 июня 2009

Фактическая работа выполняется внутри метода this.GetData(...), который не показан. Я так понимаю, это вызов веб-сервиса. Вам, вероятно, следует вызвать метод Abort() на прокси-объекте, чтобы клиент не ожидал ответа. Нет смысла вызывать CancelAsync(), просто убедитесь, что правильно проверяете ошибки в RunWorkerCompleted(). Возможно, самый простой способ - , а не - перехватывать любые исключения в _DoWork(), но проверить свойство Result.Error в Completed(). Вы все равно должны это сделать.

Просто чтобы уточнить, метод CancelAsync () полезен только для остановки цикла внутри DoWork (). Вы не запускаете (значимый) цикл там, поэтому необходим другой подход.

1 голос
/ 09 июня 2009

Обновление

Я только что проверил MSDN на DoWorkEventArgs и понял, что мой предыдущий ответ был неверным. В BackgroundWorker есть свойство CancellationPending, которое устанавливается вызовом на CancelAsync ( из MSDN ). Таким образом, ваш 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;
    }
}

Вы можете использовать это?

...