异步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简单 ...
随机推荐
- HTTP头详解
HTTP 头部解释 1. Accept:告诉WEB服务器自己接受什么介质类型,*/* 表示任何类型,type/* 表示该类型下的所有子类型,type/sub-type. 2. Accept-Chars ...
- OpenJudge计算概论-字符串排序
/*====================================================================== 字符串排序 总时间限制: 1000ms 内存限制: 6 ...
- PorterDuff.Mode error
Android PorterDuff.Mode error: PorterDuff cannot be resolved to a variable Answers: Add this t ...
- com.opensymphony.module.sitemesh.filter.PageFilter 装饰页面
1.web.xml中配置: <filter> <filter-name>sitemeshFilter</filter-name> <filter-class& ...
- Android 使用AIDL调用外部服务
好处:多个应用程序之间建立共同的服务机制,通过AIDL在不同应用程序之间达到数据的共享和数据相互操作, 本文包括: 1 .创建AIDL 服务端.2 .创建AIDL 客户端. 3.客户端调用服务端提供的 ...
- web前端基础知识及快速入门指南
web前端基础知识及快速入门指南 做前端开发有几个月了,虽然说是几个月,但是中间断断续续的上课.考试以及其它杂七杂八的事情,到现在居然一直感觉自己虽然很多前端的知识很眼熟,却也感觉自己貌似也知识在门口 ...
- 【Spring学习笔记-6】关于@Autowired与@Scope(BeanDefination.SCOPE_PROTOTYPE)
当类被@Scope(BeanDefination.SCOPE_PROTOTYPE)修饰时,说明每次依赖注入时,都会产生新的对象,具体可参见文章:http://blog.csdn.net/gst6062 ...
- 网页颜色RGB记法和16进制记法转化方法
A=>10,B=>11,C=>12,D=>13,E=>14,F=>15 看一个例子: 254,112,85 255/16 等于 15 余 14 那么它对应的应该是F ...
- RESTful API 简书
RESTful API 概述 参考地址 RESTful架构是一种流行的互联网软件架构,它结构清晰,符合标准,易于理解,扩展方便.REST是Representational State Transfer ...
- C语言每日一题之No.12
文件操作知识:如何将一个文件的内容读取到另一个文件里? fread函数和fwrite函数 1.函数功能 用来读写一个数据块. 2.一般调用形式 fread(buffer,count,siz ...