异步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简单 ...
随机推荐
- powershell samples
1,导出至EXCEL $arr =New-Object System.Collections.ArrayList $i = 1 $pstablelist = @(); $array =get-user ...
- tomcat集群待整理
对于tomcat的集群有两种方式,这个主要是针对 session而言的.一种就是sticky模式,即黏性会话模式:另外一种就是session复制模式了.所谓sticky模式就是说同一个用户的访问 请求 ...
- 012. asp.net生成验证码图片(汉字示例/字母+数字)
protected void Page_Load(object sender, EventArgs e) { //生成验证码图片的基本步骤 string checkCode = "新年快乐& ...
- SwiftyJSON 中文介绍
SwiftyJSON makes it easy to deal with JSON data in Swift. Why is the typical JSON handling in Swift ...
- SVN的分支、主干合并的使用说明
EBAPP代码SVN服务器地址:http://scm.jrj.cn/webapp/ 使用右键菜单中SVN的二级菜单Repo-Broswer查看SVN服务器目录结构 目录结构如下: 名称及功能说明: T ...
- HTTP请求方法对照表
根据HTTP标准,HTTP请求可以使用多种请求方法. HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法. HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELE ...
- ASP.NET MVC 页面调整并传递参数
转自:http://blog.csdn.net/zhensoft163/article/details/7174661 使用过ASP.NET MVC的人都知道在MVC中页面后台中常用的页面跳转方法有几 ...
- jquery动画效果---animate()--滚屏
jquery动画效果---animate()方法---W3school
- Ruby Regexp
创建正则表达式对象 #以大写字母开始后面紧跟N个数字,方式一 reg = /[A-Z]\d+/ #方式二 reg = Regexp.new("[A-Z]\d+") reg = Re ...
- 【Andorid开发框架学习】之Mina开发之服务器开发
下午那篇博客我们讲到了Mina的客户端的开发,如果还有没看过的同学可以看一下,我是传送门.现在,我们来学习一下,Mina的服务器的开发. 一.首先看一下,我的服务器的代码图片: 服务器代码我是在My ...