Фоновая отмена работника - PullRequest
1 голос
/ 21 марта 2012

У меня есть таймер и фоновый рабочий, который запускается при каждом тике таймера. Иногда мне нужно, чтобы пользователь остановил этот рабочий процесс и вызвал того же самого bg работника одним нажатием кнопки.

Так как это в Silverlight, это все асинхронно. BG работник выполняет асинхронный вызов Webservice, который асинхронно возвращает данные. Я сделал это, но это просто неправильно. Как лучше всего справиться с такой ситуацией?

button_click_event(..)
{
 _loadTimer.Stop();
                 _worker.CancelAsync();
                 _worker.RunWorkerAsync();
}

WebService call

public void GetUserStats(DateTime start, DateTime end, Action<IEnumerable<IUserStats>, Exception> callback)
    {
        _context.GetUserStatsCompleted += ContextGetUserStatsCompleted;
        _context.GetUserStatsAsync(start,end,callback);
    }

 void ContextGetUserStatsCompleted(object sender, GetUserStatsCompletedEventArgs e)
        {
            var callback = e.UserState as Action<IEnumerable<IUserStats>, Exception>;
            Exception error = null;
            var result = new ObservableCollection<IUserStats>();
            if (e.Error == null)
            {
                result = e.Result;
            }
            else
            {
                error = e.Error;
            }
            _context.GetUserStatsCompleted -= ContextGetUserStatsCompleted;
            callback(result, error);
        }

и мой рабочий

void WorkerDoWork(object sender, DoWorkEventArgs e)
        {
            TicketService.GetUserStats(StartDate, EndDate, (result, error) =>
            {

                StreamHolder = result;
            });
        }

1 Ответ

4 голосов
/ 21 марта 2012

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

if(!_worker.IsBusy) 
{
    _worker.RunWorkerAsync();
}

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

if(_worker.CancelationPending == true)
{
    e.Cancel = true;
    return;
}

Подробнее о правильном способе использования фонового работника можно прочитать здесь:

http://msdn.microsoft.com/en-us/library/cc221403(v=vs.95).aspx

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...