我想从我的.NET应用程序启动x个线程,并且我想跟踪它们,因为我需要手动终止它们或何时我的申请稍后会关闭我的申请。从我的.NET应用程序启动多个线程并跟踪它们
例==>启动线程阿尔法,启动线程测试版..然后在我的应用程序的任何一点我应该可以说终止线程测试版..
什么是跟踪打开线程的最佳途径在.NET中,我需要知道什么(一个ID?)关于一个线程来终止它? 示例代码,教程将有所帮助。
我想从我的.NET应用程序启动x个线程,并且我想跟踪它们,因为我需要手动终止它们或何时我的申请稍后会关闭我的申请。从我的.NET应用程序启动多个线程并跟踪它们
例==>启动线程阿尔法,启动线程测试版..然后在我的应用程序的任何一点我应该可以说终止线程测试版..
什么是跟踪打开线程的最佳途径在.NET中,我需要知道什么(一个ID?)关于一个线程来终止它? 示例代码,教程将有所帮助。
你可以节省自己的驴工作,并使用这个Smart Thread Pool。它提供了一个工作单位系统,允许您在任何时候查询每个线程的状态,并终止它们。
如果是太花心,然后提到的IDictionary<string,Thread>
可能是最简单的解决方案。或者也可以简单的就是给每个线程的名字,并使用IList<Thread>
:
public class MyThreadPool
{
private IList<Thread> _threads;
private readonly int MAX_THREADS = 25;
public MyThreadPool()
{
_threads = new List<Thread>();
}
public void LaunchThreads()
{
for (int i = 0; i < MAX_THREADS;i++)
{
Thread thread = new Thread(ThreadEntry);
thread.IsBackground = true;
thread.Name = string.Format("MyThread{0}",i);
_threads.Add(thread);
thread.Start();
}
}
public void KillThread(int index)
{
string id = string.Format("MyThread{0}",index);
foreach (Thread thread in _threads)
{
if (thread.Name == id)
thread.Abort();
}
}
void ThreadEntry()
{
}
}
当然,你可以得到很多非常棘手且复杂吧。如果杀死你的线程不是时间敏感的(例如,如果你不需要在3秒内杀死一个线程),那么Thread.Join()是一个更好的做法。
如果您还没有阅读过,那么Jon Skeet的this good discussion and solution针对SO上常见的“不使用中止”建议。
取决于你需要它有多复杂。你可以使用helper方法来实现你自己的ThreadPool类型。但是,我认为它很简单,就像维护一个列表/数组并相应地向集合中添加/删除线程。
您也可以使用Dictionary集合并使用您自己的特定键类型来检索它们,即Guids/strings。
创建好你的线程后,你可以设置它的Name属性。假设你将它存储在某些集合,您可以通过LINQ,以便检索(并中止)方便地访问它:
var myThread = (select thread from threads where thread.Name equals "myThread").FirstOrDefault();
if(myThread != null)
myThread.Abort();
哇,有这么多的答案..
我可以想到另外10种方式,但这些似乎工作。让我知道他们是否不适合你的需求。
您可以创建线程的字典,并将它们分配的ID,如:
Dictionary<string, Thread> threads = new Dictionary<string, Thread>();
for(int i = 0 ;i < numOfThreads;i++)
{
Thread thread = new Thread(new ThreadStart(MethodToExe));
thread.Name = threadName; //Any name you want to assign
thread.Start(); //If you wish to start them straight away and call MethodToExe
threads.Add(id, thread);
}
如果你不希望保存线程对一个ID您可以使用列表,后来只是列举其杀死线程。
当你想终止他们,你可以放弃他们。在你的MethodToExe
中有更好的条件允许该方法离开,允许线程正常终止。例如:
void MethodToExe()
{
while(_isRunning)
{
//you code here//
if(!_isRunning)
{
break;
}
//you code here//
}
}
要中止,可以列举字典并呼叫Thread.Abort()
。准备好赶上ThreadAbortException
我问过类似的问题,并收到了一堆好答案:Shutting down a multithreaded application
注:我的问题并不需要一个体面退出,但人们还是建议我优雅地从循环退出每个线程。
主要的是要记住的是,如果你想避免你的线程阻止终止,你应该将所有的线程后台的流程:
Thread thread = new Thread(new ThreadStart(testObject.RunLoop));
thread.IsBackground = true;
thread.start();
的首选方法来启动和管理线程是一个ThreadPool
,但几乎任何容器都可以用来保持对你的线程的引用。您的线程应始终有一个标志,告诉他们终止,他们应该不断检查它。
此外,为了更好地控制,您可以为线程提供CountdownLatch
:只要线程正在退出其循环,它就会在CountdownLatch
上发出信号。您的主线程将调用CountdownLatch.Wait()
方法,它会阻塞,直到所有线程都已发出信号为止......这样您可以正确清理并确保在开始清理之前,所有线程都已关闭。
public class CountdownLatch
{
private int m_remain;
private EventWaitHandle m_event;
public CountdownLatch(int count)
{
Reset(count);
}
public void Reset(int count)
{
if (count < 0)
throw new ArgumentOutOfRangeException();
m_remain = count;
m_event = new ManualResetEvent(false);
if (m_remain == 0)
{
m_event.Set();
}
}
public void Signal()
{
// The last thread to signal also sets the event.
if (Interlocked.Decrement(ref m_remain) == 0)
m_event.Set();
}
public void Wait()
{
m_event.WaitOne();
}
}
这也是值得一提的是,Thread.Abort的()方法做了一些奇怪的事情:
当一个线程调用本身中止, 效果类似于抛出 例外; ThreadAbortException 立即发生,并且结果为 可预测。但是,如果一个线程调用 在另一个线程中止时, 中止中断任何代码是 运行。也有可能中止静态构造函数。 在极少数情况下,这可能会阻止该类的实例 被在该应用程序域中创建 。在 在.NET Framework 1.0和1.1 ,有机会的话,而finally块是 运行,在这种情况下,最终 块被中止线程可能会中止。
调用线程中止可能 块是否正被 中止线程处于的 代码,被保护的区域,例如一个catch块,最后 块,或约束的执行 区域。如果调用Abort 的线程持有中止线程 需要的锁定,则会发生死锁。
当你开始每个线程时,把它的ManagedThreadId放到一个字典中作为键值和线程实例值。使用来自每个线程的回调来返回其ManagedThreadId,您可以使用它从线程终止时从线程中删除该线程。如果需要,也可以使用Dictionary来中止线程。使线程后台线程,以便他们终止,如果你的应用程序意外终止。
您可以使用单独的回调函数向线程发出信号以继续或暂停,这反映了您的UI设置的标志,以便正常退出。您还应该在线程中捕获ThreadAbortException,以便在需要中止线程时进行任何清理。
我得到了一个问题,关于void ThreadEntry(),一旦我们在线程起点的主应用程序中创建了多个线程,我们就可以启动根据分配的线程数,该线程上的任何其他应用程序。 – shawn