protected System.Threading.Thread m_searchthread = null;
问题:我已经实现了一个搜索算法,用户可以从ASP.NET网站开始。
当用户点击按钮“开始”时,执行以下代码:
m_searchthread = new System.Threading.Thread(new System.Threading.ThreadStart(Search));
m_searchthread.IsBackground = true;
m_searchthread.Start();
现在我希望能够中止搜索线程。 因此用户按下按钮“Abort”,执行此代码:
m_searchthread.Abort();
我现在的问题是:中止按钮的回发将m_searchthread重置为NULL ...
我知道线程应该使用标志中止。核心问题是:如何在松开所有变量时停止线程?
答案 0 :(得分:2)
您希望在回发之间保留的任何变量都需要进入静态变量,视图/会话状态,ASP.NET缓存或其他形式的后备存储。
当你回发时,你需要从你选择的任何后备存储中取出它。
我并不是在尝试如何执行异步任务。
发生的事情是您的线程变量是页面的本地变量。发生回发时,页面生命周期完成,并且对该变量的所有引用都将丢失。每个回发都会触发新的页面生命周期。
每当你在服务器上有一些你需要在回发之间记住的状态时,你就会遇到这个问题。 ViewState
是ASP.NET控件在回发之间记住其内容的方式,而不需要每次都重新填充它们。
答案 1 :(得分:1)
这里的直接问题是您尝试使用成员变量(字段)来存储线程。
如果你像Session["MyThreadKey"] = myThread;
一样存储它,你至少可以在下一个Postback中恢复你的线程。与myThread = Session["MyThreadKey"];
然后你可以开始考虑一种避免Thread.Abort的方法。
您可能希望将线程包装在也包含stop-flag的对象中。 (然后将该对象存储在Session中)。
如评论所述,这仅适用于单服务器解决方案。更好的方法是定义一个(WCF)服务来进行搜索。
答案 2 :(得分:0)
为什么不将标志存储在Session或ViewState中,并在页面加载事件中进行检查。
答案 3 :(得分:0)
不要从页面启动/停止作业,因为这是危险的,并且您无法控制正在运行和启动的任务。
我建议你使用Quartz.NET。在Asp.NET中使用它有一个有用的答案: How to use Quartz.net with ASP.NET
答案 4 :(得分:0)
为了根据标志停止线程,您必须按以下方式实现:
在静态类或线程可以访问的模块中定义标志本身:
bool StopTheThread = false;
在你的线程中,在你的循环中的某个地方检查这个标志,以便优雅地离开线程!
void SearchProc()
{
bool exitCond = False;
while (!exitCond)
{
//some execution
//some execution
//some execution
//check for the thread-abort flag:
if (StopTheThread)
{
System.Threading.Thread.Suspend(); //this will suspend the current thread
}
}
}