当前位置: 首页 > 编程语言 > C#

在主UI线程的Continuation中,SynchronizationContext.Current为null分享

时间:2023-04-10 20:40:03 C#

C#学习教程:SynchronizationContext.CurrentisnullinaContinuationofmainUIthread.Current在主线程上运行的任务(即.ContinueWith)中为null(我希望当前同步上下文是System.Windows.Forms.WindowsFormsSynchronizationContext)。以下是显示此问题的Winforms代码:usingSystem;使用系统线程;使用System.Threading.Tasks;使用System.Windows.Forms;namespaceWindowsFormsApplication1{publicpartialclassForm1:Form{publicForm1(){InitializeComponent();TaskSchedulerts=TaskScheduler.FromCurrentSynchronizationContext();//获取UI任务调度程序//此行是查看问题所必需的(删除此行会导致问题消失),因为它更改了//SymbolCachesrcsource.NET4DEVDIV_TFSDev10ReleasesRTMRelndpclrsrcBCLSystemThreadingExecutionContext.cs1305376ExecutionContext.cs中的代码流//在第435行Diagnostics.Trace.CorrelationManager.StartLogicalOperation("LogicalOperation");vartask=Task.Factory.StartNew(()=>{});varcont=task.ContinueWith(MyContinueWith,CancellationToken.None,TaskContinuationOptions.None,ts);System.Diagnostics.Trace.CorrelationManager.StopLogicalOperation();}voidMyContinueWith(Taskt){if(SynchronizationContext.Current==null)//当前SynchronizationContext在这里不应该为null,但它确实是。MessageBox.Show("SynchronizationContext.Current为空");这是一个问题,因为我尝试使用BackgroundWorker,并且BackgroundWorker将为其事件RunWorkerCompleted和ProgressChanged使用当前的SynchronizationContext由于当我启动BackgroundWorker时当前的SynchronizationContext为空,事件不会在主ui线程就像我想要的那样。我的问题:这是微软代码中的错误,还是我在某处犯了错误?附加信息:此问题已在.NET4.5RC中修复(刚刚测试)。所以我认为这是.NET4.0中的错误。另外,我猜这些帖子提到的是同一个问题:真不幸。现在我必须想出一个解决方法。编辑:从调试到.Net源代码,我对问题何时再次出现有了更好的了解。这是ExecutionContext.cs中的一些相关代码:internalstaticvoidRun(ExecutionContextexecutionContext,ContextCallbackcallback,Objectstate,boolignoreSyncCtx){//...此处排除的一些代码...ExecutionContextec=Thread.CurrentThread.GetExecutionContextNoCreate();如果((ec==null||ec.IsDefaultFTContext(ignoreSyncCtx))&&#ifFEATURE_IMPERSONATION||FEATURE_COMPRESSEDSTACKSecurityContext.CurrentlyInDefaultFTSecurityContext(ec)&&#endif//#ifFEATURE_IMPERSONATION||FEATURE_COMPRESSEDSTACKexecutionContext.IsDefaultFTContext(ignoreSyncCtx)){回调(状态);}else{if(executionContext==s_dummyDefaultEC)executionContext=s_dummyDefaultEC.CreateCopy();RunInternal(executionContext,回调,状态);}}问题是当我们输入调用RunInternal重现的“else”子句时。这是因为RunInternal最终替换了ExecutionContext,它具有改变当前SynchronizationContext的效果://获取当前线程上的当前SynchronizationContextpublicstaticSynchronizationContextCurrent{get{SynchronizationContextcontext=null;ExecutionContextec=Thread.CurrentThread.GetExecutionContextNoCreate();if(ec!=null){context=ec.SynchronizationContext;}//...排除了一些代码...returncontext;所以对于我的具体情况,这是因为`executionContext.IsDefaultFTContext(ignoreSyncCtx)行返回false。这是代码:internalboolIsDefaultFTContext(boolignoreSyncCtx){#ifFEATURE_CAS_POLICYif(_hostExecutionContext!=null)returnfalse;#endif//FEATURE_CAS_POLICY#ifFEATURE_SYNCHRONIZATIONCONTEXTif(!ignoreSyncCtx&&_syncContext!=null)returnfalse;#endif//#ifFEATURE_SYNCHRONIZATIONCONTEXT#ifFEATURE_IMPERSONATION||FEATURE_COMPRESSEDSTACKif(_securityContext!=null&&!_securityContext.IsDefaultFTSecurityContext())返回false;#endif//#ifFEATURE_IMPERSONATION||FEATURE_COMPRESSEDSTACKif(_logicalCallContext!=null&&_logicalCallContext.HasInfo)返回false;如果(_illogicalCallContext!=null&&_illogicalCallContext.HasUserData)返回false;返回真;}对我来说,由于_logicalCallContext.HasInfo为真,因此返回false。这是代码:publicboolHasInfo{[System.Security.SecurityCritical]//自动生成的get{boolfInfo=false;//如果存在远程处理数据,或者//安全数据或用户数据,则将标志设置为真!=null)||HasUserData){fInfo=true;}返回fInfo;}}对我来说,它返回true因为HasUserData是true。这是代码:internalboolHasUserData{get{return((m_Datastore!=null)&&(m_Datastore.Count>0));}}对我来说,因为我调用了Diagnostics.Trace.CorrelationManager.StartLogicalOperation("LogicalOperation");,m_DataStoreDiagnostics.Trace.CorrelationManager.StartLogicalOperation("LogicalOperation");中会有项目无论如何,看起来有几种不同的方法可以重现该错误。希望这个例子能帮助其他人确定他们是否遇到了同样的错误。以上是C#学习教程:在主UI线程的Continuation中,SynchronizationContext.Current为null共享所有内容。如果对你有用,需要了解更多C#学习教程,希望大家多加关注——本文来自网络合集,不代表立场,如涉及侵权,请点击右转联系管理员删除。如需转载请注明出处: