TaskFactory обрабатывает исключения

Как я могу легко обработать все исключения, которые происходят внутри задачи, которую я выполняю, не блокируя поток пользовательского интерфейса.

Я нашел много разных решений, но все они связаны с wait() функция, и это блокирует всю программу.

Задача выполняется асинхронно, поэтому она должна просто отправить сообщение потоку пользовательского интерфейса, в котором говорится, что у него есть исключения, чтобы поток пользовательского интерфейса мог его обработать. (Может быть, событие, которое я могу зацепить?)

Вот код, который у меня сейчас есть, который блокирует поток пользовательского интерфейса:

var task = Task.Factory.StartNew(() =>
{
    if (_proxy != null)
    {
        _gpsdService.SetProxy(_proxy.Address, _proxy.Port);
        if (_proxy.IsProxyAuthManual)
        {
            _gpsdService.SetProxyAuthentication(_proxy.Username,
                StringEncryption.DecryptString(_proxy.EncryptedPassword, _encryptionKey).ToString());
        }
    }

    _gpsdService.OnLocationChanged += GpsdServiceOnOnLocationChanged;
    _gpsdService.StartService();
});
try
{
    task.Wait();
}
catch (AggregateException ex)
{
    if (ex.InnerException != null)
    {
        throw ex.InnerException;
    }
    throw;
}

3 ответа

Вы не должны использовать Task.Factory.StartNew (использование Task.Run вместо). Кроме того, не используйте ContinueWith (использование await вместо).

Применяя оба эти руководства:

try
{
  await Task.Run(() =>
  {
    if (_proxy != null)
    {
      _gpsdService.SetProxy(_proxy.Address, _proxy.Port);
      if (_proxy.IsProxyAuthManual)
      {
        _gpsdService.SetProxyAuthentication(_proxy.Username,
            StringEncryption.DecryptString(_proxy.EncryptedPassword, _encryptionKey).ToString());
      }
    }

    _gpsdService.OnLocationChanged += GpsdServiceOnOnLocationChanged;
    _gpsdService.StartService();
  });
}
catch (Exception ex)
{
  // You're back on the UI thread here
  ... // handle exception
}

Вы можете подписаться на TaskScheduler.UnobservedTaskException событие

Вы используете.Net версии 4.5.2, поэтому ваша языковая версия должна быть C# 5. Таким образом, вы можете сделать следующее:

try
{
 Task t1 = await Task.Factory.StartNew(() => {

  //Do you stuff which may cause exception
 })
}
catch ()
{}

Ключевое слово await означает, что вы должны пометить свой метод асинхронным. Но это не будет блокировать и очень интуитивно понятно. Если это не сработает, воспользуйтесь идеей Дмитрия Быченко:

Task t1 = await Task.Factory.StartNew(() => {

      //Do you stuff which may cause exception
     }).ContinueWith(t=>ShowError(), TaskContinuationOptions.OnlyOnFaulted);
Другие вопросы по тегам