作者热门文章
- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我会说我拥有的以下两个代码片段是等效的,但它们不是。
以下工作正常:
var entry3 = Task.Run(async () => await entry2.GetMemberGroupsAsync(false)).WaitForResult().FirstOrDefault();
我刚刚将 Task.Run.WaitForResult
链移动到扩展方法中的以下代码不起作用,但会产生死锁:
var entry3 = entry2.GetMemberGroupsAsync(false).RunSynchronouslyAndReturnResult().FirstOrDefault();
public static T RunSynchronouslyAndReturnResult<T>(this Task<T> task)
{
return Task.Run(async () => await task).WaitForResult();
}
为什么这两个代码片段不等同?
为了完整起见,GetMemberGroupsAsync
方法由Microsoft Azure Graph API提供,函数WaitForResult定义如下。据我所知,它不会根据来电者姓名或某事做任何不同的事情。像那样:
public static TResult WaitForResult<TResult>(this Task<TResult> task,
bool continueOnCapturedContext = false)
{
if (task == null)
{
throw new ArgumentNullException("task");
}
try
{
return PreventForDeadLocks(task, continueOnCapturedContext).Result;
}
catch (AggregateException ex)
{
if (ex.InnerExceptions.Count == 1)
{
throw ex.InnerExceptions[0];
}
throw;
}
}
public static async Task<TResult> PreventForDeadLocks<TResult>(this Task<TResult> task,
bool continueOnCapturedContext = false)
{
return await task.ConfigureAwait(continueOnCapturedContext: continueOnCapturedContext);
}
最佳答案
此处的区别在于您的任务在哪个同步上下文中启动。这里:
var entry3 = Task.Run(async () => await entry2.GetMemberGroupsAsync(false)).WaitForResult().FirstOrDefault();
您在 Task.Run
调用中启动异步任务(我的意思是 await entry2.GetMemberGroupsAsync(false)
),因此不会捕获 UI 同步上下文。但是在这里:
var entry3 = entry2.GetMemberGroupsAsync(false).RunSynchronouslyAndReturnResult().FirstOrDefault();
您在 UI 上下文中隐式启动您的任务(entry2.GetMemberGroupsAsync(false)
返回 Task),因此 UI 同步上下文被捕获,并且您遇到了死锁。
关于c# - 扩展方法不等同于直接调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37678435/
判断这2个相似的Uris实际上相同的标准方法是什么? var a = new Uri("http://sample.com/sample/"); var b = new Uri("http://sam
这个问题在这里已经有了答案: Why does "true" == true show false in JavaScript? (5 个答案) 关闭 5 年前。 可能我很困惑,但我无法理解这个愚蠢
我是一名优秀的程序员,十分优秀!