我有一个表单,2个按钮,1个文本框。按钮1处理TaskException_click。 我想要做的是理解异步任务/虚空差异。但检查多个例子我仍然不理解或让它工作。在我的代码下面。 当我单击taskexception按钮时,不执行unobservedtaskexception(我预期)。 当我再次单击它时,将执行该事件,但第一次单击除外。但是UI没有更新(实际上它挂起)。想知道我做错了什么。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace test
{
public partial class main : Form
{
public main()
{
InitializeComponent();
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
}
void TaskScheduler_UnobservedTaskException(object sender, UnobservedTaskExceptionEventArgs e)
{
//textBox1.Text = "Unobserved Exception caught ";
e.SetObserved();
if (this.InvokeRequired)
{
this.Invoke((MethodInvoker)delegate()
{
//codes to do whatever i wan to do with the GUI
//Examples of it would be disposing a flowlayout panel
//and re-adding it back and populating it again to
//show the refreshed values.
textBox1.Text = "Unobserved Exception caught " + e.Exception.Message;
});
}
else
{
textBox1.Text = "Unobserved Exception caught " + e.Exception.Message;
}
}
private int i = 0;
// Add async here! You can always add these to events
private async void TaskException_Click(object sender, EventArgs e)
{
textBox1.Text = "";
try
{
Task t = TaskThrowAnException();
textBox1.Text = "done";
t = null;
Thread.Sleep(100);
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
}
catch (Exception ex)
{
textBox1.Text = "Exception caught";
}
}
private async Task TaskThrowAnException()
{
//await Task.Delay(1000);
i++;
throw new Exception("Task" + i.ToString());
}
private async void VoidException_Click(object sender, EventArgs e)
{
textBox1.Text = "";
try
{
VoidThrowAnException();
textBox1.Text = "done";
}
catch (Exception ex )
{
textBox1.Text = "Exception caught";
}
}
private async void VoidThrowAnException()
{
//await Task.Delay(1000);
throw new Exception("Void");
}
}
}
答案 0 :(得分:0)
对于TaskException
案例,异常存储在Task
中,这是返回async
的{{1}}方法的预期行为。如果您希望抛出异常,则需要等待Task
或致电Task
上的Result
或Wait()
来观察异常。
如果异常未被观察到,那么当Task
完成时它应该被抛出,我唯一可以得出的结论是,当你调用
Task
我也不确定为什么局部变量不是GCed,如果添加另一个按钮并将上面的代码放在按钮处理程序中(例如Thread.Sleep(100);
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
),一切都按预期工作。我认为生成的代码必须以某种方式链接到任务变量,但我找不到任何链接。
以下是Reflector生成的代码:
Clear_Click
}