我已经调整了一些代码,这些代码从v2.0异步结构异步执行事件到TPL。这一切似乎都运作良好,但我有一个奇怪的是我无法弄明白。
这是异步处理触发事件的类:
namespace System
{
public static class Event
{
delegate void AsyncFire(Delegate fn, object[] args);
private static async Task UnsafeFireAsync(Delegate fn, params object[] args)
{
if (fn == null)
return;
Delegate[] callList = fn.GetInvocationList();
List<Task> taskList = new List<Task>();
AsyncFire asyncFire = InvokeDelegate;
foreach (Delegate sink in callList)
{
var tcs = new TaskCompletionSource<object>();
asyncFire.BeginInvoke(sink, args, AsyncCallback, tcs);
taskList.Add(tcs.Task);
}
await Task.Factory.ContinueWhenAll(taskList.ToArray(), null);
}
static void AsyncCallback(IAsyncResult ar)
{
AsyncFire asyncFire = InvokeDelegate;
var tcs = (TaskCompletionSource<object>)ar.AsyncState;
try
{
asyncFire.EndInvoke(ar);
tcs.SetResult(null);
}
catch(Exception e)
{
tcs.SetException(e);
}
}
static void InvokeDelegate(Delegate fn, object[] args)
{
fn.DynamicInvoke(args);
}
public static async Task FireAsync(EventHandler fn, object sender)
{
await UnsafeFireAsync(fn, sender, EventArgs.Empty);
}
public static async Task FireAsync<T>(EventHandler<T> fn, object sender, T e) where T : EventArgs
{
await UnsafeFireAsync(fn, sender, e);
}
}
}
然后我有一个提供一些事件的类和一些子调用它们:
namespace AsyncEventTest
{
class AsyncEvents
{
public event EventHandler Event1;
public event EventHandler Event2;
public event EventHandler Event3;
public event EventHandler Event4;
public event EventHandler<StringEventArgs> Event5;
public void DoProcess()
{
Event1(this, EventArgs.Empty);
Event2(this, EventArgs.Empty);
Event3(this, EventArgs.Empty);
Event4(this, EventArgs.Empty);
Event5(this, new StringEventArgs("Event 5 parameter"));
}
public async Task DoProcessPartialAsync()
{
await Task.Factory.StartNew(DoProcess);
}
public async Task DoProcessFullAsync()
{
Task[] taskList = new Task[5];
taskList[0] = Event.FireAsync(Event1, this);
taskList[1] = Event.FireAsync(Event2, this);
taskList[2] = Event.FireAsync(Event3, this);
taskList[3] = Event.FireAsync(Event4, this);
taskList[4] = Event.FireAsync(Event5, this, new StringEventArgs("Event 5 parameter"));
await Task.Factory.ContinueWhenAll(taskList, null);
}
}
}
然后我有一个来自它的调用AsyncEvents类并使用它的事件:
public partial class Form1 : Form
{
AsyncEvents events = new AsyncEvents();
public Form1()
{
InitializeComponent();
events.Event1 += events_Event1;
events.Event2 += events_Event2;
events.Event3 += events_Event3;
events.Event4 += events_Event4;
events.Event5 += events_Event5;
}
void events_Event5(object sender, StringEventArgs e)
{
System.Threading.Thread.Sleep(4000);
AddToEventList("Event 5 Message: " + e.Message);
}
void events_Event4(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(1000);
AddToEventList("Event 4 Done");
}
void events_Event3(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(2000);
AddToEventList("Event 3 Done");
}
void events_Event2(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(500);
AddToEventList("Event 2 Done");
}
void events_Event1(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(2500);
AddToEventList("Event 1 Done");
}
private void FireAsyncBtn_Click(object sender, EventArgs e)
{
AsyncOutputList.Items.Clear();
events.DoProcessPartialAsync().ContinueWith(t => AddToEventList("DoProcess call done"));
AddToEventList("DoProcess call returned");
}
private void FireFullAsyncBtn_Click(object sender, EventArgs e)
{
AsyncOutputList.Items.Clear();
events.DoProcessFullAsync().ContinueWith(t => AddToEventList("DoProcess call done"));
AddToEventList("DoProcess call returned");
}
private void AddToEventList(string msg)
{
if (InvokeRequired)
{
Invoke((Action<string>)AddToEventList, msg);
return;
}
AsyncOutputList.Items.Add(msg);
}
}
部分异步调用按预期运行:
完全异步调用虽然在事件执行完毕之前执行ContinueWith:
我的问题是,为什么?我不明白为什么&#34; DoProcess Done&#34;线路正在提前输出。