我有wpf应用程序,让我们称之为A-app。A-app使用后台工作人员运行异步B-method。这个B-method位于一个不同的项目中,它为B-method init部分创建了几个线程。
用户可以要求运行B-method,也可以要求取消运行并重新启动。问题是,如果它在init时间内被取消,运行B-method的后台工作人员就会被取消,但是线程不会取消。重新启动会创建更多的线程,这些线程不能与以前运行的线程同时工作,并且会导致一些错误。
线程方法主要是等待。
如何停止B-method并取消它创建的线程?
一个不同的AppDomain可以在任何方面有所帮助吗?(而不是关闭整个应用程序域?)如果是的话,该怎么办呢?有更好的办法吗?
详细信息:
发布于 2014-08-06 12:50:12
我建议您不要创建线程,而是使用TaskScheduler并使用并行任务库:
http://msdn.microsoft.com/en-us/library/dd997402%28v=vs.110%29.aspx
TaskScheduler本身就是处理线程的ThreadPool的包装器。它甚至可以做一些诸如WorkStealing、Task等方面的工作。
最好从这里开始:http://msdn.microsoft.com/en-us/library/dd997402%28v=vs.110%29.aspx
另一种方法是使用CancalletionToken启动任务,这使您能够取消任务。见此处:http://msdn.microsoft.com/en-us/library/dd537607%28v=vs.110%29.aspx
编辑:好的,没有TPL,阻塞线程。这基本上只剩下Thread.Abort。这很麻烦,但是没有完美的世界,所以把表单想象为应用程序A,ClassB是应用程序B:
public partial class MainWindow : Window
{
Thread _threadA;
Thread _threadB;
Thread _threadC;
ClassB b1 = new ClassB();
ClassB b2 = new ClassB();
ClassB b3 = new ClassB();
public MainWindow()
{
InitializeComponent();
_threadA = new Thread(() => b1.DoSomeWork("A"));
_threadB = new Thread(() => b2.DoSomeWork("B"));
_threadC = new Thread(() => b3.DoSomeWork("C"));
}
private void btnStartWork_Click(object sender, RoutedEventArgs e)
{
_threadA.Start();
_threadB.Start();
_threadC.Start();
}
private void btnStopThreadA_Click(object sender, RoutedEventArgs e)
{
AbortThreadA();
}
private void btnStopThreadB_Click(object sender, RoutedEventArgs e)
{
AbortThreadB();
}
private void btnStopThreadC_Click(object sender, RoutedEventArgs e)
{
AbortThreadC();
}
private void AbortThreadA()
{
_threadA.Abort();
}
private void AbortThreadB()
{
_threadB.Abort();
}
private void AbortThreadC()
{
_threadC.Abort();
}
private void btnStopAll_Click(object sender, RoutedEventArgs e)
{
AbortThreadA();
AbortThreadB();
AbortThreadC();
}
}
class ClassB
{
public void DoSomeWork(string threadIdentifier)
{
try
{
string preWorkString = "Work work Okeydokey. Thread: " + threadIdentifier;
string postWorkString = "Job's Done. Thread: " + threadIdentifier;
while (true)
{
System.Diagnostics.Debug.WriteLine(preWorkString);
Thread.Sleep(5000);
System.Diagnostics.Debug.WriteLine(postWorkString);
}
}
catch (ThreadAbortException)
{
System.Diagnostics.Debug.WriteLine("Thread aborted. Thread: " + threadIdentifier);
Thread.ResetAbort();
}
}
}需要ResetAbort,否则错误会冒泡。
这是可能的解决办法吗?
发布于 2014-08-07 09:38:32
你拥有B方法(你能改变它吗?)
我假设B-方法在本质上是不可取消的,而您只是取消在模块A中调用它的后台工作人员吗?
B-方法需要更改为可取消,或重新进入.对于可重入者,我的意思是它将允许对自身进行多个调用,并将重用任何已经在进行中的现有init序列。
https://stackoverflow.com/questions/25160604
复制相似问题