<code class="lang-c">async Task<int> DelayAsync(int n) { await Task.Delay(n); return n; } void Button1Click(object sender, EventArgs e) { int n = AsyncHelper.AsyncInline.Run(async () => { return await DelayAsync(1000); }); MessageBox.Show(n.ToString()); }</int></code>
<code class="lang-c">using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; namespace AsyncHelper { public static class AsyncInline { // 使用方法:AsyncInline.Run(async () => { ... }); public static void Run(Func<task> item) { var oldContext = SynchronizationContext.Current; var synch = new ExclusiveSynchronizationContext(); SynchronizationContext.SetSynchronizationContext(synch); synch.Post(async _ => { try { await item(); } catch (Exception e) { synch.InnerException = e; throw; } finally { synch.EndMessageLoop(); } }, null); synch.BeginMessageLoop(); SynchronizationContext.SetSynchronizationContext(oldContext); } // 使用方法:var retval = AsyncInline.Run(async () => { ... }); public static T Run<t>(Func<task<t>> item) { var oldContext = SynchronizationContext.Current; var synch = new ExclusiveSynchronizationContext(); SynchronizationContext.SetSynchronizationContext(synch); T ret = default(T); synch.Post(async _ => { try { ret = await item(); } catch (Exception e) { synch.InnerException = e; throw; } finally { synch.EndMessageLoop(); } }, null); synch.BeginMessageLoop(); SynchronizationContext.SetSynchronizationContext(oldContext); return ret; } private class ExclusiveSynchronizationContext : SynchronizationContext { private bool done; public Exception InnerException { get; set; } readonly AutoResetEvent workItemsWaiting = new AutoResetEvent(false); readonly Queue<tuple<sendorpostcallback, object>> items = new Queue<tuple<sendorpostcallback, object>>(); public override void Send(SendOrPostCallback d, object state) { throw new NotSupportedException("We cannot send to our same thread"); } public override void Post(SendOrPostCallback d, object state) { lock (items) { items.Enqueue(Tuple.Create(d, state)); } workItemsWaiting.Set(); } public void EndMessageLoop() { Post(_ => done = true, null); } public void BeginMessageLoop() { while (!done) { Tuple<sendorpostcallback, object> task = null; lock (items) { if (items.Count > 0) { task = items.Dequeue(); } } if (task != null) { task.Item1(task.Item2); if (InnerException != null) // the method threw an exeption { throw new AggregateException("AsyncInline.Run method threw an exception.", InnerException); } } else { workItemsWaiting.WaitOne(); } } } public override SynchronizationContext CreateCopy() { return this; } } } }</sendorpostcallback,></tuple<sendorpostcallback,></tuple<sendorpostcallback,></task<t></t></task></code>
[修改于 8年8个月前 - 2016/04/17 12:17:06]
时段 | 个数 |
---|---|
{{f.startingTime}}点 - {{f.endTime}}点 | {{f.fileCount}} |