async与await【二】死锁之解决办法

async/await可以更新UI线程,但还是有一定问题存在,比如如下情况会造成死锁。
遇到的问题:

private void button1_Click(object sender, EventArgs e) {
    Task<string> res = GetResAsync();
    textBox1.Text = res.Result;
}

private async Task<string> GetResAsync() {
    string t = await Task.Run(() => {
        Thread.Sleep(1000);
        return "返回结果";
    });
    return t;
}

只要点击button就会造成线程死锁,原因:
await时会获取当前线程的SychronizationContext,而res.Result等待await执行完成,await等待获取SychronizationContext,造成死锁

解决方案1:在await前就把SychronizationContext获取了
缺点:
1、res.Result时会等待,容易造成界面无响应
2、SetSynchronizationContext(null)容易出现副作用

private void button1_Click(object sender, EventArgs e) {
    Task<string> res = GetResAsync();
    textBox1.Text = res.Result;
}

private async Task<string> GetResAsync() {
    //获取当前线程的SychronizationContext
    SynchronizationContext syncContext = WindowsFormsSynchronizationContext.Current;
    //设置当前线程的SychronizationContext为null
    WindowsFormsSynchronizationContext.SetSynchronizationContext(null);
    string t = await Task.Run(() => {
        Thread.Sleep(1000);
        return "返回结果";
    });
    //设置当前线程的SychronizationContext
    WindowsFormsSynchronizationContext.SetSynchronizationContext(syncContext);
    return t;
}

解决方案2:再套一层Task.Run
缺点:
1、res.Result时会等待,容易造成界面无响应
2、await无法直接更新UI界面

private void button1_Click(object sender, EventArgs e) {
    Task<string> res = Task.Run(GetResAsync);
    textBox1.Text = res.Result;
}

private async Task<string> GetResAsync() {
    string t = await Task.Run(() => {
        Thread.Sleep(1000);
        return "返回结果";
    });
    return t;
}

:https://blog.youkuaiyun.com/qq_42690327/article/details/125631980

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值