同步调用异步方法帮助类:

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());

来源链接

http://social.msdn.microsoft.com/Forums/en/async/thread/163ef755-ff7b-4ea5-b226-bbe8ef5f4796

同步调用异步方法how-would-i-run-an-async-taskt-method-synchronously的更多相关文章

  1. 尝试解决在构造函数中同步调用Dns.GetHostAddressesAsync()引起的线程死锁

    (最终采用的是方法4) 问题详情见:.NET Core中遇到奇怪的线程死锁问题:内存与线程数不停地增长 看看在 Linux 与 Windows 上发生线程死锁的后果. Linux: Microsoft ...

  2. .NET中如何在同步代码块中调用异步方法

    更新记录 本文迁移自Panda666原博客,原发布时间:2021年7月2日. 在同步代码块中调用异步方法,方法有很多. 一.对于有返回值的Task 在同步代码块中直接访问 Task 的 Result ...

  3. HttpClient中异步方法的同步调用

    在System.Net.Http中,提供了使用Http与远程服务器通讯的httpClient,但是里面都是异步方法,有时候我们并不需要使用异步操作.这个时候可以使用如下的方式来进行同步调用. clas ...

  4. 又踩.NET Core的坑:在同步方法中调用异步方法Wait时发生死锁(deadlock)

    之前在将 Memcached 客户端 EnyimMemcached 迁移 .NET Core 时被这个“坑”坑的刻骨铭心(详见以下链接),当时以为只是在构造函数中调用异步方法(注:这里的异步方法都是指 ...

  5. 委托(delegate)的三种调用方式:同步调用,异步调用,异步回调(转载)

    下面为即将被调用的方法: public delegate int AddHandler(int a,int b); public class 加法类 { public static int Add(i ...

  6. C# 委托的三种调用示例(同步调用 异步调用 异步回调)

    首先,通过代码定义一个委托和下面三个示例将要调用的方法: 复制代码 代码如下: public delegate int AddHandler(int a,int b);    public class ...

  7. 似是而非的JS - 异步调用可以转化为同步调用吗?

    源起 小飞是一名刚入行前端不久的新人,因为进到了某个大公司,俨然成为了学弟学妹眼中'大神',大家遇到js问题都喜欢问他,这不,此时他的qq弹出了这样一条消息 "hi,大神在吗?我有个问题想问 ...

  8. 一码阻塞,万码等待:ASP.NET Core 同步方法调用异步方法“死锁”的真相

    在我们 2015 年开始的从 .NET Framework 向 .NET Core 迁移的工程中,遇到的最大的坑就是标题中所说的--同步方法中调用异步方法发生"死锁".虽然在 .N ...

  9. 异步多线程 ASP.NET 同步调用异步 使用Result产生死锁

    一个方法调用了async方法,要将这个方法本身设计为async. public class BlogController : Controller { public async Task<Act ...

随机推荐

  1. C语言基础一(敲打键盘、寻找资料)

    事前声明一点:小编的所有材料都是基础,没有什么大的不同,您若觉得不错的话,可以互相探讨下,毕竟本人也是小雏鸟. 大家在学习C语言.C++类似的高端语言时候,往往都是为了学而学,殊不知为什么而学,或许更 ...

  2. GitHub用法

    注意: 在push之前要先git pull origin融合代码使得本地代码版本更新,从而才能进行push!! 详细内容参见->这里 本篇内容转自->这里 作者:知乎用户链接:https: ...

  3. python系统编程(八)

    进程VS线程 功能 进程,能够完成多任务,比如 在一台电脑上能够同时运行多个QQ 线程,能够完成多任务,比如 一个QQ中的多个聊天窗口 定义的不同 进程是系统进行资源分配和调度的一个独立单位. 线程是 ...

  4. 2017.07.14【NOIP提高组】模拟赛B组

    Summary 这次比赛因为迟到了,少了很多时间,也受到了相应的惩罚,这是好的,是个标记牌,警醒着我.这次比赛的题目很难,也就是说,大家的得分都很低,总的来说,收获还是很大的,因为有非常多的技巧被掌握 ...

  5. BLEU (Bilingual Evaluation Understudy)

    什么是BLEU? BLEU (Bilingual Evaluation Understudy) is an algorithm for evaluating the quality of text w ...

  6. nvidia-smi命令输出详解

    nvidia-smi命令输出如下: +-----------------------------------------------------------------------------+ | ...

  7. 多个组件联合打印输出——PrintableComponentLink

    DevExpress强大到难以想象,其很多组件.接口.自定义事件可完成较好的效果,可节省不少事.如下图所示,用的两个ChartControl.一个GridControl制作的平断面示意图,里面涉及不少 ...

  8. linux 杀死进程

    列车进程 ps -ef 杀死进程 - 后面是pid kill 1234356

  9. 运行Keras版本的Faster R-CNN(1)

    Keras版本的Faster R-CNN源码下载地址:https://github.com/yhenon/keras-frcnn下载以后,用PyCharm打开(前提是已经安装了Tensorflow-g ...

  10. Spring MVC框架处理Web请求的基本流程