异步task处理
public async Task<Customers> GetCustomers()
{
return await Service.GetCustomersAsync();
}
public async void GetCustomers()
{
customerList = await GetCustomers();
}
引用方法 http://stackoverflow.com/questions/5095183/how-would-i-run-an-async-taskt-method-synchronously
public static class AsyncHelpers
{
/// <summary>
/// Execute's an async Task<T> method which has a void return value synchronously
/// </summary>
/// <param name="task">Task<T> method to execute</param>
public static void RunSync(Func<Task> task)
{
var oldContext = SynchronizationContext.Current;
var synch = new ExclusiveSynchronizationContext();
SynchronizationContext.SetSynchronizationContext(synch);
synch.Post(async _ =>
{
try
{
await task();
}
catch (Exception e)
{
synch.InnerException = e;
throw;
}
finally
{
synch.EndMessageLoop();
}
}, null);
synch.BeginMessageLoop(); SynchronizationContext.SetSynchronizationContext(oldContext);
} /// <summary>
/// Execute's an async Task<T> method which has a T return type synchronously
/// </summary>
/// <typeparam name="T">Return Type</typeparam>
/// <param name="task">Task<T> method to execute</param>
/// <returns></returns>
public static T RunSync<T>(Func<Task<T>> task)
{
var oldContext = SynchronizationContext.Current;
var synch = new ExclusiveSynchronizationContext();
SynchronizationContext.SetSynchronizationContext(synch);
T ret = default(T);
synch.Post(async _ =>
{
try
{
ret = await task();
}
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("AsyncHelpers.Run method threw an exception.", InnerException);
}
}
else
{
workItemsWaiting.WaitOne();
}
}
} public override SynchronizationContext CreateCopy()
{
return this;
}
}
}
调用:
customerList = AsyncHelpers.RunSync<List<Customer>>(() => GetCustomers());
也可以使用如下方式:
.Net 4.5 下
// For Task<T>: will block until the task is completed...
var result = task.Result; // For Task (not Task<T>):
task2.RunSynchronously();
.Net 4.0 下
var x = (IAsyncResult)task;
task.Start(); x.AsyncWaitHandle.WaitOne(); 或: task.Start();
task.Wait();
还有一个开源项目:https://github.com/tejacques/AsyncBridge/blob/master/src/AsyncBridge/AsyncHelper.cs
using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks; namespace AsyncBridge
{
using EventTask = Tuple<SendOrPostCallback, object>;
using EventQueue = ConcurrentQueue<Tuple<SendOrPostCallback, object>>; /// <summary>
/// A Helper class to run Asynchronous functions from synchronous ones
/// </summary>
public static class AsyncHelper
{
/// <summary>
/// A class to bridge synchronous asynchronous methods
/// </summary>
public class AsyncBridge : IDisposable
{
private ExclusiveSynchronizationContext CurrentContext;
private SynchronizationContext OldContext;
private int TaskCount; /// <summary>
/// Constructs the AsyncBridge by capturing the current
/// SynchronizationContext and replacing it with a new
/// ExclusiveSynchronizationContext.
/// </summary>
internal AsyncBridge()
{
OldContext = SynchronizationContext.Current;
CurrentContext =
new ExclusiveSynchronizationContext(OldContext);
SynchronizationContext
.SetSynchronizationContext(CurrentContext);
} /// <summary>
/// Execute's an async task with a void return type
/// from a synchronous context
/// </summary>
/// <param name="task">Task to execute</param>
/// <param name="callback">Optional callback</param>
public void Run(Task task, Action<Task> callback = null)
{
CurrentContext.Post(async _ =>
{
try
{
Increment();
await task; if (null != callback)
{
callback(task);
}
}
catch (Exception e)
{
CurrentContext.InnerException = e;
}
finally
{
Decrement();
}
}, null);
} /// <summary>
/// Execute's an async task with a T return type
/// from a synchronous context
/// </summary>
/// <typeparam name="T">The type of the task</typeparam>
/// <param name="task">Task to execute</param>
/// <param name="callback">Optional callback</param>
public void Run<T>(Task<T> task, Action<Task<T>> callback = null)
{
if (null != callback)
{
Run((Task)task, (finishedTask) =>
callback((Task<T>)finishedTask));
}
else
{
Run((Task)task);
}
} /// <summary>
/// Execute's an async task with a T return type
/// from a synchronous context
/// </summary>
/// <typeparam name="T">The type of the task</typeparam>
/// <param name="task">Task to execute</param>
/// <param name="callback">
/// The callback function that uses the result of the task
/// </param>
public void Run<T>(Task<T> task, Action<T> callback)
{
Run(task, (t) => callback(t.Result));
} private void Increment()
{
Interlocked.Increment(ref TaskCount);
} private void Decrement()
{
Interlocked.Decrement(ref TaskCount);
if (TaskCount == )
{
CurrentContext.EndMessageLoop();
}
} /// <summary>
/// Disposes the object
/// </summary>
public void Dispose()
{
try
{
CurrentContext.BeginMessageLoop();
}
catch (Exception e)
{
throw e;
}
finally
{
SynchronizationContext
.SetSynchronizationContext(OldContext);
}
}
} /// <summary>
/// Creates a new AsyncBridge. This should always be used in
/// conjunction with the using statement, to ensure it is disposed
/// </summary>
public static AsyncBridge Wait
{
get { return new AsyncBridge(); }
} /// <summary>
/// Runs a task with the "Fire and Forget" pattern using Task.Run,
/// and unwraps and handles exceptions
/// </summary>
/// <param name="task">A function that returns the task to run</param>
/// <param name="handle">Error handling action, null by default</param>
public static void FireAndForget(
Func<Task> task,
Action<Exception> handle = null)
{
#if NET_45
Task.Run(
#elif NET_40
TaskEx.Run(
#endif
() =>
{
((Func<Task>)(async () =>
{
try
{
await task();
}
catch (Exception e)
{
if (null != handle)
{
handle(e);
}
}
}))();
});
} private class ExclusiveSynchronizationContext : SynchronizationContext
{
private readonly AutoResetEvent _workItemsWaiting =
new AutoResetEvent(false); private bool _done;
private EventQueue _items; public Exception InnerException { get; set; } public ExclusiveSynchronizationContext(SynchronizationContext old)
{
ExclusiveSynchronizationContext oldEx =
old as ExclusiveSynchronizationContext; if (null != oldEx)
{
this._items = oldEx._items;
}
else
{
this._items = new EventQueue();
}
} 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)
{
_items.Enqueue(Tuple.Create(d, state));
_workItemsWaiting.Set();
} public void EndMessageLoop()
{
Post(_ => _done = true, null);
} public void BeginMessageLoop()
{
while (!_done)
{
EventTask task = null; if (!_items.TryDequeue(out task))
{
task = null;
} if (task != null)
{
task.Item1(task.Item2);
if (InnerException != null) // method threw an exeption
{
throw new AggregateException(
"AsyncBridge.Run method threw an exception.",
InnerException);
}
}
else
{
_workItemsWaiting.WaitOne();
}
}
} public override SynchronizationContext CreateCopy()
{
return this;
}
}
}
}
异步task处理的更多相关文章
- C#异步Task编程模型实战手册
一.课程介绍 本次分享课程属于<C#高级编程实战技能开发宝典课程系列>中的第一部分,阿笨后续会计划将实际项目中的一些比较实用的关于C#高级编程的技巧分享出来给大家进行学习,不断的收集.整理 ...
- Framework4.5语法糖 异步Task
1.线程安全 在使用TaskRun的时候需要注意线程安全的问题. 线程安全通常是由全局变量及静态变量引起的,如果是值类型就不存在这样的隐患,如果是引用类型用不好就会导致线程不安全! 2.Task.Ta ...
- C#多线程和异步——Task和async/await详解
阅读目录 一.什么是异步 二.Task介绍 1 Task创建和运行 2 Task的阻塞方法(Wait/WaitAll/WaitAny) 3 Task的延续操作(WhenAny/WhenAll/Cont ...
- Task C# 多线程和异步模型 TPL模型
Task,异步,多线程简单总结 1,如何把一个异步封装为Task异步 Task.Factory.FromAsync 对老的一些异步模型封装为Task TaskCompletionSource 更通用, ...
- 『审慎』.Net4.6 Task 异步函数 比 同步函数 慢5倍 踩坑经历
异步Task简单介绍 本标题有点 哗众取宠,各位都别介意(不排除个人技术能力问题) —— 接下来:我将会用一个小Demo 把 本文思想阐述清楚. .Net 4.0 就有了 Task 函数 —— 异步编 ...
- C# 异步编程3 TPL Task 异步程序开发
.Net在Framework4.0中增加了任务并行库,对开发人员来说利用多核多线程CPU环境变得更加简单,TPL正符合我们本系列的技术需求.因TPL涉及内容较多,且本系列文章为异步程序开发,所以本文并 ...
- C#.NET使用Task,await,async,异步执行控件耗时事件(event),不阻塞UI线程和不跨线程执行UI更新,以及其他方式比较
使用Task,await,async,异步执行事件(event),不阻塞UI线程和不跨线程执行UI更新 使用Task,await,async 的异步模式 去执行事件(event) 解决不阻塞UI线程和 ...
- Task C# 多线程和异步模型 TPL模型 【C#】43. TPL基础——Task初步 22 C# 第十八章 TPL 并行编程 TPL 和传统 .NET 异步编程一 Task.Delay() 和 Thread.Sleep() 区别
Task C# 多线程和异步模型 TPL模型 Task,异步,多线程简单总结 1,如何把一个异步封装为Task异步 Task.Factory.FromAsync 对老的一些异步模型封装为Task ...
- Net4.6 Task 异步函数 比 同步函数 慢5倍 踩坑经历
Net4.6 Task 异步函数 比 同步函数 慢5倍 踩坑经历 https://www.cnblogs.com/shuxiaolong/p/DotNet_Task_BUG.html 异步Task简单 ...
随机推荐
- noip2011普及组——统计单词数
统计单词数 时间限制:1 s 内存限制:128MB [问题描述]一般的文本编辑器都有查找单词的功能,该功能可以快速定位特定单词在文章中的位置,有的还能统计出特定单词在文章中出现的次数.现在,请你编程实 ...
- wikioi 1160 蛇形矩阵
/*======================================================================== 1160 蛇形矩阵 题目描述 Descriptio ...
- vs2010编译lua-5.3.2
lua-5.3.2.tar.gz 解开在 D:\lua 1. 启动VS命令行 2. c:\program files\microsoft visual studio 10.0\vc\bin>cd ...
- sqlserver 字符串拼接及拆开联表查询的问题
一.sql根据一个以逗号隔开的人员guid类型的ID字符串查出其对应的姓名同样拼接成逗号隔开的字符串: 1.需求:管理员发送通知(通知分为普通通知,奖品订单,调查问卷三种类型)给用户,并且可以查看统计 ...
- Android Camera 相机程序编写
Android Camera 相机程序编写 要自己写一个相机应用直接使用相机硬件,首先应用需要一个权限设置,在AndroidManifest.xml中加上使用设备相机的权限: <uses-per ...
- smarty变量
前台: 注释的两种方式:<{**}>和<!--注释html代码-->比如: <{* <div style="width:100px; height:100 ...
- HTML 文本格式化
HTML 可定义很多供格式化输出的元素,比如粗体和斜体字. 下面有很多例子,您可以亲自试试: HTML 文本格式化实例 文本格式化 此例演示如何在一个 HTML 文件中对文本进行格式化 预格式文本 此 ...
- LintCode "Digit Counts" !!
Lesson learnt: one effective solution for bit\digit counting problems: counting by digit\bit http:// ...
- Python列表,元组,字典,序列,引用
1.列表 # Filename: using_list.py # This is my shopping list shoplist=["apple", "mango&q ...
- 【Linux】系统 之 RAID
本人从事DBA相关的工作,最近遇到了IO抖动伴随shread running抖动的情况,主机宕机重启后备库及下游解析binlog出现损坏的案例,向一些有经验的同事咨询学习,其中最大的嫌疑是:raid卡 ...