如何在 ASP.Net 调用队列用户工作项期间保留执行线程的上下文?



我们有一个ASP。. NET应用程序,该应用程序使用System.Threading.ThreadPool.QueueUserWorkItem将其一些长时间运行的操作(例如生成报告)排队到ThreadPool

这种方法有两个问题:

  1. 我们运行ASP。Net应用程序池使用特定的域服务帐户,以便它可以访问远程资源,包括文件和数据库。当线程在ThreadPool中开始执行时,线程的用户标识被设置为Network Service,这就不允许我们访问远程资源。

  2. web应用程序可以被不同国家的用户同时访问,我们提供给每个用户的数据格式是基于他们的文化设置(使用web.config中的标准全球化设置)。当队列线程启动时,它也会丢失此信息,并恢复到操作系统的默认区域性。

现在,我们可以通过在状态对象中捕获当前用户身份和文化并将其传递给后台worker,然后模拟用户并在线程上设置文化来解决大多数问题,但这似乎非常"不干净"。解决这个问题的方法。

有更好的方法吗?

附加信息:

以下是web.config的全球化设置:

<globalization requestEncoding="utf-8" responseEncoding="utf-8" culture="auto" enableClientBasedCulture="true" uiCulture="auto"></globalization>

当一个请求被处理时,ASP. NET自动将当前线程的CultureUICulture设置为用户请求的区域性(在Accept-Language头中由浏览器自动传递)。

这种行为可以通过在后面的代码中添加以下代码来复制(即按钮点击,页面加载等):

' Called from just about anywhere
ThreadInitiator()
Private Sub ThreadInitator()
   ' Observe the culture and windowsidentity here; they will be correct
   System.Threading.ThreadPool.QueueUserWorkItem(AddressOf Testing, new Object)
End Sub
Private Sub Testing(state As Object)
   ' Observe the culture and windowsidentity here; they will not be what we need them to be
End Sub

方法签名:

public static bool QueueUserWorkItem(
    WaitCallback callBack,
    Object state
)

接受状态对象。这可以是一个类的实例,其中包含用户的文化和任何需要持久化的其他项。此信息被传播回回调方法,您可以将其强制转换回类的实例。

您应该做的第一件事是考虑而不是具有来自ASP.NET的长时间运行进程。实际上,您应该尝试将任何长时间运行的流程卸载到它所属的服务中。Windows Service、WCF等

System.Threading.ThreadPool.QueueUserWorkItem(AddressOf Testing, New Object())

这可能是文化相关信息的问题。您必须将标识传递给回调方法。

最新更新