不能产生sspi上下文_简单理解线程同步上下文

为了线程安全,winform和wpf框架中规定只能使用UI线程操作控件,从其它线程上操作控件就会报跨线程异常。假如有这样一个场景:点击按纽,然后开始计算员工薪资,并将计算信息实时展示在一个文本框中,由于计算过程比较耗时,为了不让界面卡死,我们会将计算方法放在单独一个线程中。UI代码如下: 557e108dec936636033cafb7f5af9ea7.png 薪资计算类代码如下: 5e332f9d36b8a47ad23e16f947b138f0.png 上面的代码就不过多解释了,相信大家都看的懂。按纽点击后,开启一个新线程,执行计算,并将更新UI的方法以委托的形式传给SalaryCalculator类。我们执行一下,如下: dd9e8bdbbe0e2963fd4acada2a1f72a3.png 不出意外,报错了,我们不能在新线程中更新UI线程。一般的做法,我们可以使用Invoke,这个大家应该都用烂了。改写下ShowMessage,代码如下: 72da55c09cefcc410ca77ebf68d67a0e.png 除了以上办法,我们还可以使用SynchronizationContext来解决上面的问题。这个类,大家可能比较陌生, 我们来看一下它的定义,如下: a6c781d28b27adab50aa91605b863156.png 它的定义:提供在各种同步模型中传播同步上下文中的基本功能。其实它的含义就是对当前线程上下文的封装,或者叫当前线程所在环境的封装。封装的对象可以传递至其他线程,然后在其他线程中调用其Post或Send方法,以此来实现线程间的消息传播。我们使用SynchronizationContext修改上面的代码,得到的结果都是一样。代码如下: c143d34e4d01ee37990bc1a7658eb2b3.png d689754049e9a4b6f4dd709ab4b39a35.png 上面的代码中,先通过SynchronizationContext.Current获取UI线程的同步上下文对象,然后在计算薪资的线程中使用这个对象的Post方法,这时控制是在UI线程的上下文中执行,所以不会报错。 讲到这里,其实SynchronizationContext的内容就讲完了,不过有个点可以再补充下。大家应该知道Task对象有一个ConfigureAwait()方法,用来配置是否同步上下文,我们到这个方法中看一下,代码如下: 080635f4774cb52a67b26d97b878842f.png continueOnCapturedContext尝试将延续任务封送回原始上下文件,默认为true。这里说的原始上下文,其实就是SynchronizationContext,即异步前(await)前所在的线程的同步上下文。我们将Calculate改成异步方法,代码如下: 3e2fff1d57193649accfc736ac6a3701.png 我们知道,异步方法在遇到await之前都在当前线程中执行,当执行完await这行后,方法就会退出,然后会将await之后的代码封装成委托(可能不太准确,大概这个意思,会产生一个状态机类,不展开讨论)。在执行await时,默认会捕获当前的线程上下文,然后当执行完Task.Delay(1000)后,上面说的线程上下文就会将剩下的代码发回(Post/Send)自己的线程执行。大概像下面这个样子,代码如下: 5cd7663426295fca80f7226c40cd2d53.png 上面代码不一定准确,只是想表达这个意思。如果我们不想剩下来的代码在原来的上下文中执行,可以将continueOnCapturedContext设为false,这也是微软推荐的做法。不然会出现一些意想不到的情况,比如死锁。我们看一下调用的地方,代码如下: bf6b1164db2d929e1260d6335b1ce1ff.png 我们配置了不捕获上下文,这时代码是正常运行的。我们再来演示一下经典的死锁问题吧,如果你还有兴趣就接着向下看吧。我们改造下上面的代码,改成同步等待,并默认捕获上下文。代码如下: 7eeabd7a8b592b2407e19b5199103679.png 我们定义task变量,并去除ConfigureAwait(false),这样在Calculate中默认会捕获上下文。下面的task.Wait()会等待task完成,可是我们在线程上下文中又会执行Post方法,这时互相等待,造成死锁。解决办法:用到异步的地方都加上ConfigureAwait(false),另一个不要使用Wait方法,用异步就异步到底。 终于讲完了,今天讲的内容还是很简单,如果能帮到你一点点,我就会很开心的(能关注下就更好),哈哈。 最后PS一下这个demo的界面图吧,让你们看看我的设计能力~~ d0877d646a0bed9eaa364d5ef6a008ff.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值