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