如何找出特定线程何时退出(C#)?

时间:2014-12-12 05:50:13

标签: c# multithreading

我这里有问题。有没有办法以编程方式找出某个线程退出的时刻?我的意思是,即使VS调试器在其“输出”窗口中提供了该信息。我知道我只是可以让我的线程来引发一个事件,但是当你产生多个线程时,这当然会导致一个问题,因此每个线程都会引发该事件,除非你使用一些切换变量来确保只有在代码中到达该点的第一个线程将引发事件。

这是在多个线程中执行的方法的开始,此处显示了取消,暂停和退出逻辑。代码的问题点是对事件处理程序的调用(DownloadComplete,DownloadPaused和DownloadCanceled)。正如您所看到的,其中一些将仅由到达该点的第一个线程执行一次,然后切换相关的bool变量,因此其他线程不会再次引发此事件。这里的另一个大问题是线程退出逻辑,当线程没有找到要下载的项目并返回时,下载完成事件当然将被每个线程触发。这两种方法都不正确,我目前不知道如何实现我的预期行为。我需要的是如何找到一种方法来捕捉所有产生的线程的最后一个结束,所以我可以只提出一次上面提到的所有事件。

请注意,我没有访问System.Threading.Tasks命名空间中的类型,因为我的项目针对.net 2.0。这是我第一次使用编程比某些类赋值更复杂的经验,所以我意识到这段代码很可能是各种各样的糟糕。

抱歉我的英文。

    private void PerformDownload()
    {
        while (true)
        {
            if (askedToCancel)
            {
                lock (lockObj)
                {
                    if (!cancellationPerformed)
                    {
                        cancellationPerformed = true;

                        foreach (DownloadItem di in itemsToProcess)
                            if (di.Status == DownloadItemStatus.Prepared)
                                itemsToProcess.UpdateItemStatus(di.URL, DownloadItemStatus.Canceled);

                        DownloadCanceled();
                    }
                }

                return;
            }

            if (askedToPause)
            {
                lock (lockObj)
                {
                    if (!pausingPerformed)
                    {
                        foreach (DownloadItem di in itemsToProcess)
                            if (di.Status == DownloadItemStatus.Prepared)
                                itemsToProcess.UpdateItemStatus(di.URL, DownloadItemStatus.Paused);

                        DownloadPaused();
                    }
                }

                waitHandle.WaitOne();
            }

            DownloadItem currentItem = null;

            lock (lockObj)
            {
                foreach (DownloadItem di in itemsToProcess)
                    if (di.Status == DownloadItemStatus.Prepared)
                    {
                        currentItem = di;
                        itemsToProcess.UpdateItemStatus(currentItem.URL, DownloadItemStatus.Downloading);
                        break;
                    }
            }

            if (currentItem == null)
            {
                DownloadComplete();
                return;
            }

1 个答案:

答案 0 :(得分:1)

您可以在计数器上使用Interlocked.Increment()Interlocked.Decrement(),在线程的入口点递增,在线程退出时递减。然后,如果计数器非零,则该线程的至少一个实例正在运行。

例如:

private int _threadCounter;

private void ThreadEntryPoint()
{
    try
    {
        Interlocked.Increment(ref _threadCounter);
        // Do thread stuff here
    }
    finally
    {
        Interlocked.Decrement(ref _threadCounter);
    }
}

也就是说,对于重要线程是否正在运行,恕我直言不太可能是最好的设计。也就是说,每当我想到如何使用这些信息时,我觉得有更好的方法来解决这个问题。

线程存在的原因不仅仅是存在。那么你的代码真正应该关心的是这个原因是否得到了解决,而不是是否有任何线程正在运行。如果没有完整的代码示例,我无法对特定场景发表评论。但我怀疑跟踪实际的线程存在是不太有用的,并且比更注重目标的方法更难维护。