- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
为了澄清我的问题,我一直在开发一个应用程序,它根据用户的输入(使用 excel 电子表格)执行大量数据库更新/网络服务调用。如果有很多更新,则该过程可能需要超过 20 分钟才能运行。
为了阻止我的 UI 卡住/超时,我一直在研究多线程,这样我就可以以异步方式运行长时间运行的进程,同时在进程运行时简单地显示动画 gif。
这一切似乎在我的测试数据下运行良好,但是当我在实际的长时间运行的过程中进行替换时,我得到了一个关于 HttpContext.Current.User.Identity.Name 的错误。我已经阅读了这个和这个 article1我的意思是,如果您在页面指令中将“Async”属性设置为“true”并使用 RegisterAsyncTask 方法,您就可以访问 HttpContext.Current。然而,对我来说这似乎不是真的。我确定这是我正在做的事情,所以这是我的代码(我主要使用以下文章来编写此 article2 和 article3 ):
ASP.NET 页面
<%@ Page Title="Home Page" Async="true" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="false" CodeBehind="Index.aspx.cs" Inherits="MyApp.Index" %>
C# - RegisterAsyncTask 通过单击按钮完成,这会启动长时间运行的进程:
protected void ProcessUpdates()
{
//Register async task to allow the processing of valid updates to occurr in the background
PageAsyncTask task = new PageAsyncTask(OnBegin, OnEnd, OnTimeOut, null);
RegisterAsyncTask(task);
}
IAsyncResult OnBegin(Object sender, EventArgs e, AsyncCallback cb, object state)
{
return Worker.BeginWork(cb, state);
}
private void OnEnd(IAsyncResult asyncResult)
{
//UpdateResults list should now have been filled and can be used to fill the datagrid
dgProcessedUpdates.DataSource = Worker.UpdateResults;
dgProcessedUpdates.CurrentPageIndex = 0;
dgProcessedUpdates.DataBind();
lblProgress.Text = "Update Results: update success / failure is shown below";
}
private void OnTimeOut(IAsyncResult asyncResult)
{
lblProgress.Text = "The process has timed out. Please check if any of the updates have been processed.";
}
C# - worker 类
public class Worker
{
public static List<AuditResult> UpdateResults = new List<AuditResult>();
private delegate void del();
//This method is called when the thread is started
public static IAsyncResult BeginWork(AsyncCallback cb, object state)
{
del processing = DoUpdateProcessing;
return processing.BeginInvoke(cb, state);
}
private static void DoUpdateProcessing()
{
//UpdateResults = ExcelFileProcessing.PassValidUpdates();
//Testing
Thread.Sleep(5000);
int i = 0;
while(i < 10)
{
AuditResult ar = new AuditResult();
ar.Result = "Successful";
ar.JobNumber = (1000 + i).ToString();
ar.NewValue = "Test New Value " + i.ToString();
ar.ResultDate = DateTime.Now.ToString();
ar.UserName = HttpContext.Current.User.Identity.Name;
UpdateResults.Add(ar);
i++;
}
}
}
最初,我的测试代码不包括对 ar.UserName 的 HttpContext.Current.User.Name 调用,但在我重新调用 ExcelFileProcessing.PassValidUpdates() 时遇到问题后,我决定这样做。当我到达该部分 (ar.UserName = HttpContext.Current.User.Identity.Name) 时,它说“对象引用未设置为对象的实例”,这表明 HttpContext 未传递到第二个线程。我该怎么做?
更新
我目前已恢复到我以前的代码(最初无法正常工作)并根据此 SO question 将 HttpContext.Current 作为变量传递给我的 DoWork 方法像这样:
创建第二个线程
protected void ProcessValidUpdates()
{
Worker workerObject = new Worker();
HttpContext ctx = HttpContext.Current;
Thread workerThread = new Thread(new ThreadStart(() =>
{
HttpContext.Current = ctx;
workerObject.DoWork();
}));
workerThread.Start();
//Loop until worker thread activates
while (!workerThread.IsAlive) ;
//Put main thread to sleep to allow the worker thread to do some work
Thread.Sleep(1000);
//Request the worker thread stop itself
workerObject.RequestStop();
//Use the Join method to block the current thread until the object's thread terminates
workerThread.Join();
//UpdateResults list should now have been filled and can be used to fill the datagrid
dgProcessedUpdates.DataSource = Worker.UpdateResults;
dgProcessedUpdates.CurrentPageIndex = 0;
dgProcessedUpdates.DataBind();
lblProgress.Text = "Update Results: update success / failure is shown below";
}
worker 类(Class)
public class Worker
{
//volatile hints to the compiler that this data member will be accessed by multiple threads.
private volatile bool _shouldStop;
public static List<AuditResult> UpdateResults = new List<AuditResult>();
//This method is called when the thread is started
public void DoWork()
{
while (!_shouldStop)
{
//Testing
Thread.Sleep(5000);
int i = 0;
while (i < 10)
{
AuditResult ar = new AuditResult();
ar.Result = "Successful";
ar.JobNumber = (1000 + i).ToString();
ar.NewValue = "Test New Value " + i.ToString();
ar.ResultDate = DateTime.Now.ToString();
ar.UserName = HttpContext.Current.User.Identity.Name;
UpdateResults.Add(ar);
i++;
}
}
}
public void RequestStop()
{
_shouldStop = true;
}
}
这似乎有效,因为我现在可以访问 HttpContext.Current 和我期望的用户名。我认为这可能在某种程度上是你们中的一些人所提议的。我很欣赏 Andrew Morton 建议的解决方案,但目前需要进行重大重写。目前我的进程已经调用了一个网络服务来处理数据库并返回成功或失败的结果。它还必须直接调用另一个 BPEL 服务。因此,我怀疑如果我必须将所有这些都包装到另一个 Web 服务中,可能会进一步影响性能。此外,大多数对该进程的调用不会运行那么长时间(可能少于 10 分钟),因此这实际上只是为了解决少数超过 20 分钟的请求。最后,这只可能被 1 或 2 个人使用,因此不太可能在 1 次有大量请求。
但是,考虑到我目前的解决方案,有什么我应该注意的可能会绊倒我的地方吗? IIS 导致问题?非常感谢任何额外的帮助。
最佳答案
我在共享服务器上有一个站点。我需要有一个 BATCH 作业,我在另一个线程中完成。它最多可以运行 1 小时(我对站点执行 ping 操作,因此工作进程不会停止)。
我沿着搭售的道路去获取当前的上下文。经过数小时的研究和搜索,它无法完成。在新线程中,httpcontent.current 不存在,它与用户访问的线程不同,因此上下文没有延续,并且您无法访问已登录的用户,因为他们没有登录到该线程。
关于c# - 多线程时如何使用 HttpContext.Current?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25164154/
我是 HangFire 的初学者,期待使用 HangFire 每月在我的网络应用程序中调用一些操作。但是这些操作需要 HttpContext。 那么我的问题是:有没有办法在 HangFire 项目中添
是 HttpContext.Current.User 在全局 asax 中与 不同HttpContext.User 在 Action 方法中?我为用户分配了一些角色,但他们似乎迷路了。 下面的代码显示
我不明白 HttpContext.Handler 和 HttpContext.CurrentHandler 之间有什么区别。 任何人? 最佳答案 微软: CurrentHandler 属性引用的当前正
这两种获取当前 asp.net 请求异常的方法之间有什么实际区别吗? MSDN 说 HttpContent.Error 返回第一个错误,而 GetLastError() 显然是最后一个错误,但我似乎无
我正在使用 httphandler。在 ProcessRequest 中传递的 HttpContext 是否引用了 HttpContext.Current?使用它们有什么不同吗? 最佳答案 是的,两者
我目前正在处理一些遗留代码,其中 HttpContext.Current.User 属性在 MVC Controller 方法中用于对当前用户执行一些基本授权。通过阅读文档,还有一个 HttpCont
我们正在迁移应用程序以使用 IIS7 集成模式。在设计为在 HTTP 请求上下文或不在上下文中工作的库代码中,我们通常有这样的代码: if (HttpContext.Current != null &
我想知道 Web API Controller 中的 HttpContext.Request.Path 和 HttpContext.Request.PathBase 有什么区别?我阅读了文档但不明白有
我真的无法找出 C#/.NET 中这两种方法之间的真正区别。 事实上他们应该做同样的 Action ! 最佳答案 第一个包含一个安全的读/写存储位置,可以在整个 HTTP 请求中使用。例如,您可以使用
想知道 - HttpContext.Response.Cache 和 HttpContext.Current.Cache 对象有什么区别?以及在 Asp.net MVC Web 应用程序中应该使用什么
我的 Controller 有这样声明的用法(不确定顺序是否重要) using System; using System.Collections.Generic; using System.Linq;
我的团队正在开发一个基于 ASP.NET Core Web 应用程序 (.NET Framework) 模板构建的新项目。由于遗留原因,我们有另一个项目构建在 System.Web 上,并通过 Htt
如果我想存储一些对象以在页面和 session 之间共享,我应该使用哪一个? HttpContext.Current.ApplicationInstance.Application 或 HttpCon
这 2 个似乎有些含糊不清。我在整个项目中交替使用它们,唯一的原因是我不知道何时使用其中一个。 在什么情况下一个为真而另一个为假? 如果我只使用 ASP.NET Identity 来对用户进行身份验证
我正在开发一个 ASP.NET web 应用程序,我想实现缓存,所以我想知道 HttpContext.Current.Cache.Insert 和 HttpContext.Current 之间的区别.
这两个属性有什么区别? 我可以使用 HttpContext.Items 而不是 HttpContext.Features 在中间件之间共享数据。我看到的唯一区别是我告诉 Items 一个键,它给了我一
微软的HttpContext.Current.Request.ServerVariables[“REMOTE_ADDR”]正在为远程客户端返回ipv6。但是,我需要将此数据用于一个会话日志表,其中的C
if (HttpContext.Current.Request.Cookies.AllKeys.Contains("myCookie") && !String.IsNullOrEmpty(Ht
我有一个项目作为引用添加到 System.Web。 但是,它似乎无法获取 HttpContext。这样做: Imports System.Web _ApplicationBase = HttpCont
我创建了这个类来从请求中获取 Header 值。 public class AuthenticationHeader { private static IHttpContextAccesso
我是一名优秀的程序员,十分优秀!