加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

为什么在使用当前同步上下文启动任务时,不设置ASP.NET HttpConte

发布时间:2020-12-16 00:37:47 所属栏目:asp.Net 来源:网络整理
导读:我正在玩.NET的异步功能,并提出了一个我无法真正解释的情况。在同步ASP.NET MVC控制器中执行以下代码时 var t = Task.Factory.StartNew(()={ var ctx = System.Web.HttpContext.Current; //ctx == null here},CancellationToken.None,TaskCreationOptions.N
我正在玩.NET的异步功能,并提出了一个我无法真正解释的情况。在同步ASP.NET MVC控制器中执行以下代码时
var t = Task.Factory.StartNew(()=>{
        var ctx = System.Web.HttpContext.Current;
        //ctx == null here
},CancellationToken.None,TaskCreationOptions.None,TaskScheduler.FromCurrentSynchronizationContext()
);

t.Wait();

委托中的ctx为null。现在我的理解,当您使用TaskScheduler.FromCurrentSynchronizationContext()任务调度程序时,上下文应该还原。那为什么不在这里? (我可以,btw,看到代理在同一个线程上同步执行)。

另外,从msdn起,TaskScheduler.FromCurrentSynchronizationContext()的行为如下:

All Task instances queued to the returned scheduler will be executed
through a call to the Post method on that context.

但是,当我使用这个代码:

var wh = new AutoResetEvent(false);

SynchronizationContext.Current.Post(s=> {
    var ctx = System.Web.HttpContext.Current;
    //ctx is set here
    wh.Set();
    return;
},null);

wh.WaitOne();

上下文实际设置。

我知道这个例子是有点无可比拟的,但我真的很想知道在.NET上如何增加对异步编程的理解。

解决方法

你的看法似乎是正确的,这有点令人费解。
您将调度程序指定为“TaskScheduler.FromCurrentSynchronizationContext()”。这将关联一个新的“SynchronizationContextTaskScheduler”。现在,如果你看这个类,它使用:

So if the task scheduler has access to the same “Synchronization
Context” and that should reference
“LegacyAspNetSychronizationContext”. So surely it appears that
HttpContext.current should not be null.

在第二种情况下,当您使用SychronizationContext(参见:MSDN Article)时,线程的上下文与任务共享:

“Another aspect of SynchronizationContext is that every thread has a
“current” context. A thread’s context isn’t necessarily unique; its
context instance may be shared with other threads.”

在这种情况下,SynchronizationContext.Current由LegacyAspNetSychronizationContext提供,内部引用了HttpApplication。

当Post方法必须调用注册的回调时,它调用HttpApplication.OnThreadEnter,这最终导致当前线程的上下文设置为HttpCurrent.Context:

这里引用的所有类在框架中被定义为内部,并且使得进一步的调查有点难。

PS:说明SynchornizationContext对象实际上指向“LegacyAspNetSynchronizationContext”:

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读