#c_sharp #исключения #async_await
Есть код скачивания файлов, на нижнем уровне есть простой цикл с ограничением, чтобы сделать несколько попыток скачивания, выглядит упрощенно вот так: private static bool Failed = false; static void Main(string[] args) { TaskScheduler.UnobservedTaskException += (o, a) => { throw a.Exception; }; ChapterDownload().Wait(); } public static async Task ChapterDownload() { try { var pages = Enumerable.Range(0, 20); var pTasks = pages.Select(page => { return PageDownload() .ContinueWith(t => Console.WriteLine("{0}{1}", t.Status, t.IsFaulted)); }); await Task.WhenAll(pTasks.ToArray()); } catch (Exception ex) { // } } public static async Task PageDownload() { if (Failed) throw new Exception("boom"); try { // var file = await new WebClient().DownloadDataTaskAsync(new Uri(@"http://example.com")); var file = await DownloadFile(new Uri(@"http://example.com")); if (file != null) throw new Exception("Restart download, downloaded file is corrupted"); } catch (Exception ex) { Failed = true; await PageDownload(); } } public static async TaskDownloadFile(Uri uri) { byte[] result; WebResponse response; var request = WebRequest.Create(uri); try { response = await request.GetResponseAsync(); using (var memory = new MemoryStream()) { await response.GetResponseStream().CopyToAsync(memory); result = memory.ToArray(); } } catch (System.Exception ex) { return null; } if (response.ContentLength == result.LongLength) return result; return null; } Проблема в чём - в текущем виде, происходит UnobservedTaskException, с текстовкой boom, т.е. явно моё. При этом, стоит мне заменить скачивание с самопала на webclient - UnobservedTaskException больше не возникает. В чём разница?
Ответы
Ответ 1
Чтобы исключения задачи (Task) считались обработанными и не вызывали событие TaskScheduler.UnobservedTaskException необходимо их перевыбросить, например t.Result, t.Wait() или t.GetAwaiter().GetResult(), или просмотреть, обратившись с свойству Exception: t.Exception. В Вашем коде проблема возникает потому, что вы ждёте завершение не самих исходных задач, а их продолжений. В то время как продолжения не делают ничего, чтобы обработать исключения исходных задач. В результате исключения, возникшие в исходных задачах, остаются необработанными.
Комментариев нет:
Отправить комментарий