同步调用异步函数时被调用者的线程会发生什么

罗希特·沙玛(Rohit Sharma)

在下面的示例中,当异步调用“ Process”函数时,可以看到对“ await Task.Delay(1000)”的调用导致UI挂起。

我知道我可以通过调用“ await Task.Delay(1000).ConfigureAwait(false)”或将“ Process”调用包装在另一个任务中来避免挂起。我可以理解问题在于synchornizationcontext,并且我知道await正在做一些花哨的事情,即如果我将UI的调用“ await Task.Delay(1000)”替换为“ Task.Delay(1000).Wait()”,不挂。

有人可以解释一下这种行为吗(我曾尝试查看ildasm代码,但没有帮助)。非常感谢。

public MainWindow()
{
    InitializeComponent();
    Loaded += OnLoaded;
}

public async void OnLoaded(object sender, RoutedEventArgs args)
{
    var task = Process();
    MessageBox.Show(task.Result);
}

public async Task<String> Process()
{
    await Task.Delay(1000);
    return "";
}
dtb

首先,方法总是被同步调用。OnLoaded被调用时,它会调用该Process方法。

Process方法调用该Task.Delay方法并返回Task<string>对其等待对象的引用这意味着await后面的代码将在以后执行,并且该Process方法将在此时返回。

OnLoaded方法获取Task<string>对其存储在task变量中对象的引用然后Result在任务上调用getter。这将阻塞当前线程,直到任务完成。

一秒钟后,该Process方法尝试继续。因为您是在UI线程上启动任务的,所以调度程序会尝试Process在UI线程上调度方法。但是UI线程被Resultgetter调用阻塞,因此该return "";语句从不执行。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么在循环中涉及异步调用的递归函数不返回到调用者函数以继续循环?

从一定同步调用者异步方法(Vert.x,JAVA)

具有同步和异步调用者的同步方法中的Thread.Sleep或Task.Delay

同步调用异步Javascript函数

lua同步调用C异步函数

同步调用异步方法时出错

如果进行单个同步调用,Webflux中会发生什么?

使用可调用对象时主线程会发生什么

如何在不阻塞主线程的情况下同步调用异步函数?

完成一个异步调用后,将响应返回给调用者

调用线程的interrupt()会发生什么?

同步方法上的等待/异步,什么是“异步进程”?“控制权何时返回给调用者”?嵌套等待

在同步代码库中异步调用函数

当几个线程试图调用相同的同步方法时会发生什么?

调用者未“完成”的“收益”枚举-发生了什么

为什么仅调用同步函数时javascript promises异步?

RequireJS何时需要异步调用?什么时候同步?

使同步调用异步时如何返回TaskStatus?

同步异步发出的异步调用

调用setState()函数会发生什么?

异步调用 lambda 函数

异步调用模板函数

当您在Swift中的同步队列中异步调度任务时会发生什么?

Objective-C中的同步和异步调用与多线程之间有什么区别?

如果我在非异步函数中调用 `AsyncStorage.setItem` 而没有 await 会发生什么?

同步Lambda调用-受到限制时会发生什么?

当客户端处理或超出范围时,异步WCF调用会发生什么情况?

如果我使用JNI从C的多个线程中调用Java函数,会发生什么情况?

使科特林异步调用同步