从任务调用异常

时间:2018-04-15 01:12:57

标签: c# winforms

我在库中有一个方法,它没有包含在Task.Factory语法中的任何控件,我想正确处理它将抛出的异常并在UI中显示消息。请考虑以下代码:

Project.WinForms:

public void button1_Click(object sender, EventArgs e)
{
    try
    {
        library1.RunTask();
    }
    catch(Exception Ex)
    {
        MessageBox.Show(Ex.Message);
    }
}

Project.Core:

public void RunTask()
{
    Task.Factory.StartNew(() => {
        try
        {
            throw new Exception("SAMPLE_EXCEPTION");
        }
        catch(Exception)
        {
            throw;
        }
    });
}

运行已编译的可执行文件时发生的事情是没有显示Exception,UI处于类似进程的状态,但实际上,另一个线程中发生了异常。但是,在调试解决方案时,会抛出异常,从而破坏代码的执行,如下所示:

enter image description here

1 个答案:

答案 0 :(得分:5)

您的Task方法是异步的,并且会抛出异常。官方文档有一节link 2,其中说明:

  

要捕获异常,请等待try块中的任务,并捕获关联的catch块中的异常。

所以,让我们做两处改变:

  1. 返回您在RunTask()
  2. 中开始的await
  3. // Use the async keyword, // so we can use await in the method body public async void button1_Click(object sender, EventArgs e) { try { // await the completion of the task, // without blocking the UI thread await RunTask(); } catch (Exception ex) { Console.WriteLine(ex.Message); } } // Change the signature to return a Task public Task RunTask() { // Return the task that you started return Task.Factory.StartNew(() => { throw new Exception("SAMPLE_EXCEPTION"); }); } // The following emulates your button click scenario public event EventHandler<EventArgs> ButtonClickEvent; public static void Main() { var p = new Program(); p.ButtonClickEvent += p.button1_Click; p.ButtonClickEvent(p, new EventArgs()); } 您的事件处理程序中的try块中的任务。
  4. 以下是您的方案的exceptions in async methods

    async void

    为了更全面地解释发生了什么,我建议您a simplified example

    但有一个重要的事项需要注意。我们从button1_Click事件处理程序返回async Task,即使它几乎总是Async/Await - Best Practices in Asynchronous Programming。但事件处理程序必须返回void,因此我们无法使用async void,而必须使用import 'package:flutter/material.dart'; import 'dart:io'; void main() => runApp(new MyApp()); class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return new MaterialApp( home: new ImageIcon( new AssetImage( "assets/images/image.png"), size: 24.0, color: Colors.white), ); } }