我在库中有一个方法,它没有包含在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处于类似进程的状态,但实际上,另一个线程中发生了异常。但是,在调试解决方案时,会抛出异常,从而破坏代码的执行,如下所示:
答案 0 :(得分:5)
您的Task
方法是异步的,并且会抛出异常。官方文档有一节link 2,其中说明:
要捕获异常,请等待try块中的任务,并捕获关联的catch块中的异常。
所以,让我们做两处改变:
RunTask()
。await
// 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块中的任务。以下是您的方案的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),
);
}
}
。