双SynchronizationContext同步请求造成UI死锁

代码

private void btnRun_Click(object sender, EventArgs e)
{
    var sc = SynchronizationContext.Current;
    //①
    sc.Send(o =>
    {
	btnRun.Text = DateTime.Now.ToString();
	var t = new Thread(() =>
	{
	    //②
	    sc.Send(oo =>
	    {
		Thread.Sleep(1000);
		btnRun.Text = DateTime.Now.ToString();
	    }, null);
	});
	t.Start();
	t.Join();
    }, null);
}

解释

①处开始占用SynchronizationContext,并开始同步执行一直等待②处执行完毕。但②处也申请占用SynchronizationContext以将自己的代码执行完毕。砰~DeadLock条件成立!

解决

将同步调用改成异步,破坏死锁条件。将②处的“sc.Send”改成“sc.Post”即可。

结论

牵涉到“同步”与“资源占用”的话,要注意是否可能会造成死锁。

个人挺不愿花许多心思在业务代码上,乱刀斩乱麻,直接避免“同步”与“资源占用”,即避免使用SynchronizationContext.Send(),统一使用SynchronizationContext.Post()。

参考

UI thread client callback和UI thread WCF Service一起工作时死锁的形成原因及解决方法


转载于:https://www.cnblogs.com/beta2013/archive/2012/06/30/3377297.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值