【发布时间】:2021-01-14 19:40:49
【问题描述】:
我需要将旧应用程序中的状态管理从 inProc 更改为 StateServer。
有在新线程中执行的方法。
代码如下所示。
protected void btnTransaction_Click(object sender, EventArgs e)
{
timerTrans.Enabled = true;
timerTrans.Interval = 200;
Thread thread = new Thread(new ParameterizedThreadStart(DoAllWork));
thread.Start(dbConnectionString);
}
public void DoAllWork(object connectionString)
{
DBAccess dba = new DBAccess(connectionString.ToString());
Session["NextTransactionId"] = dba.getNewTransactionId();
//Other work
foreach(transaction t in transactions)
{
ShowTrasnactionStatus("Processing transaction "+t.id);
}
//Other work
Session["FinalStatus"] = "All Transactions Completed";
Session["TransactionStatus"] = "Done";
}
private void ShowTrasnactionStatus(string statusMsg)
{
Session["TransactionStatus"] = statusMsg;
}
protected void timerTrans_Tick(object sender, EventArgs e)
{
lblStatus.Text = Session["TransactionStatus"].ToString();
if (Session["TransactionStatus"].ToString() == "Done")
{
//Final Stage of Transaction Processing
lblStatus.Text = "Getting final status ...";
billEndTime = DateTime.Now;
ShowFinalStatus();
timerBilling.Enabled = false;
}
}
启用网络花园后,使用会话变量更新状态不会按预期工作。
- 我尝试过使用类变量而不是会话变量。
- 使用缓存而不是会话。
它们都不适合我。
注意:此代码来自至少 8 年前开发的现有应用程序。
我只想在不破坏功能的情况下在网络花园中运行它。
【问题讨论】:
-
使用那个线程你什么也得不到,web 请求已经在它们自己的线程中执行了。如果您想执行一项长期运行的作业,那在 8 年前也是错误的做法,而且只是偶然地起作用 - IIS 对该线程一无所知,因此只要请求完成,它就可以免费 GC 任何资源。会话可能会在该线程仍在运行时关闭。检查The Dangers of implementing recurring background tasks in ASP.NET
-
还要检查How to run background tasks in ASP.NET,它显示了长时间运行作业的可用机制。该问题没有显示任何 实际 正在完成的工作,只有一些有风险的控制更新,因此很难推荐一种或另一种技术。也许根本不需要线程?也许您可以使用异步/等待?也许您确实需要一种方法来运行长时间的工作并显式将数据传递给它?
-
真正的问题是如何报告进度以跟踪长期运行的作业并将其显示给用户?并显示它以响应 ASP.NET 旧更新面板投票?即使没有会话处于活动状态,该作业也会运行,因此使用会话是有风险的。轮询也很昂贵,这就是为什么应用程序使用 SignalR 从客户端向浏览器发送消息的原因。
-
@PanagiotisKanavos 感谢 cmets。这解释了很多。对于这个应用程序 SingleR 不是一个选项。另外,我不愿意对运行了 8 年的代码做任何大的改动。
-
那么您唯一的选择就是保持原样,因为如果不进行这些更改,您将无法在网络花园中运行它。
标签: c# asp.net .net multithreading web-garden