简体   繁体   English

查看线程未正确结束

[英]See thread not correctly ended

I'm developing a project on Visual Studio 2015 using C# and WPF. 我正在使用C#和WPF在Visual Studio 2015上开发一个项目。 Sometimes I quit my running project with my close command, and sometimes with the stop debug button. 有时,我使用close命令退出正在运行的项目,有时使用Stop debug按钮退出。 The problem is that after a few tests, my PC starts to warm and the fans make noise. 问题是经过几次测试后,我的电脑开始发热,风扇发出噪音。 I have to quit Visual Studio to calm the machine. 我必须退出Visual Studio才能使计算机平静下来。

So I have questions : 所以我有问题:

  • How to see the threads not ended after a test ? 如何查看测试后线程未结束?
  • When I know them, how to properly end them ? 当我知道它们时,如何正确结束它们? (actually I Dispose some threads when WindowClosing ) (实际上,我在WindowClosingDispose一些线程)
  • How make sure that thread will properly ends when I use the stop debug button ? 当我使用停止调试按钮时,如何确保线程正确结束?

Thank you 谢谢

EDIT: 编辑:

There is the screenshot of task manager. 有任务管理器的屏幕截图。 When I start application the CPU rise from 5% to 15% (or event 25%). 当我启动应用程序时,CPU从5%上升到15%(或事件25%)。 RAM rise from 4GO to 4.5. RAM从4GO上升到4.5。 When I stop application, CPU goes to 45% for a few seconds and go back to 5% but RAM goes to 4.70GO and doesn't go back down. 当我停止应用程序时,CPU会在几秒钟内达到45%的速度,然后又回到5%,但是RAM达到4.70GO,并且没有下降。

任务管理器

EDIT2: 编辑2:

I founded this kind of thread on my application: 我在应用程序上建立了这种线程:

private bool isClosing = false;
public void Start()
{
    isClosing = false;
    ThreadPool.QueueUserWorkItem(new WaitCallback(doWorkThread));
}

public void Stop()
{
    isClosing = true;
}

private AutoResetEvent endPoolStateButton = new AutoResetEvent(false);
private void doWorkThread(object sender)
{
    Action action = new Action(() => doWork());
    while (!isClosing)
    {
        Thread.Sleep(100);
        this.Dispatcher.BeginInvoke(action, System.Windows.Threading.DispatcherPriority.Background);
    }
    endPoolStateButton.Set();
}

private void doWork()
{
    /* Job performed */
}

I wonder if there is a really good way to use thread ? 我想知道是否有使用线程的好方法? If application close without setting isClosing = true the while never stop. 如果应用程序关闭且未设置isClosing = true ,则isClosing = true永不停止。 And the thread is never really aborted ? 而且线程永远不会真正中止? Do you think that this kind of thread can cause all the troubles I have ? 您是否认为这种线程会引起我的所有麻烦?

Here is my solution how to stop thread in elegant way. 这是我的解决方案,如何以优雅的方式停止线程。 Hope the code is clear. 希望代码清楚。 I use CancellationToken to cancel operations in thread and ManualResetEvent to wait for thread cancellation: 我使用CancellationToken取消线程中的操作,并使用ManualResetEvent等待线程取消:

namespace ElegantThreadWork
{
    using System;
    using System.Threading;
    using System.Diagnostics;

    class ThreadObject
    {
        public CancellationToken CancellationToken { get; private set; }
        public ManualResetEvent WaitHandle { get; private set; }

        public ThreadObject(CancellationToken ct, ManualResetEvent wh)
        {
            CancellationToken = ct;
            WaitHandle = wh;
        }
    }
    public class Program
    {
        static void DoWork(CancellationToken ct)
        {
            Console.WriteLine("Thread[{0}] started", Thread.CurrentThread.ManagedThreadId);
            int i = 0;
            // Check for cancellation on each iteration
            while (!ct.IsCancellationRequested)
            {
                // Do something
                Console.WriteLine("Thread[{0}]: {1}", Thread.CurrentThread.ManagedThreadId, i);
                // Wait on CancellationToken. If cancel be called, WaitOne() will immediatly return control!
                // You can see it by elapsed time
                ct.WaitHandle.WaitOne(TimeSpan.FromSeconds(1));
                i++;
            }
            Console.WriteLine("Thread[{0}] has been cancelled", Thread.CurrentThread.ManagedThreadId);
        }
        static void ThreadProc(object state)
        {
            ThreadObject to = (ThreadObject)state;
            try
            {
                DoWork(to.CancellationToken);
            }
            finally
            {
                to.WaitHandle.Set();
            }
        }
        public static void Main(string[] args)
        {
            TimeSpan MAX_THREAD_EXITING_TIMEOUT = TimeSpan.FromSeconds(5);

            // Use for elegant thread exiting
            ManualResetEvent isThreadExitedEvent = new ManualResetEvent(false);
            CancellationTokenSource cts = new CancellationTokenSource();
            ThreadObject threadObj = new ThreadObject(cts.Token, isThreadExitedEvent);

            // Create thread
            Thread thread = new Thread(ThreadProc, 0);
            thread.Start(threadObj);

            Console.WriteLine("Just do something in main thread");

            Console.WriteLine("Bla.");
            Thread.Sleep(1000);

            Console.WriteLine("Bla..");
            Thread.Sleep(1000);

            Console.WriteLine("Bla...");
            Thread.Sleep(1000);

            Console.WriteLine("Thread cancelattion...");
            Stopwatch sw = Stopwatch.StartNew();
            // Cancel thread
            cts.Cancel();

            // Wait for thread exiting
            var isOk = isThreadExitedEvent.WaitOne(MAX_THREAD_EXITING_TIMEOUT);
            sw.Stop();
            Console.WriteLine("Waiting {0} for thread exiting. Wait result: {1}. Cancelled in {2}", MAX_THREAD_EXITING_TIMEOUT, isOk, sw.Elapsed);

            // If we couldn't stop thread in elegant way, just abort it
            if (!isOk)
                thread.Abort();
        }
    }
}

Maybe you can try to observe the behaviour of the process and the threads with the tool "Process Hacker". 也许您可以尝试使用“ Process Hacker”工具观察进程和线程的行为。 With this tool you get more detailed informations about the thread and you also can detect deamon threads. 使用此工具,您可以获得有关线程的更多详细信息,并且还可以检测到守护进程线程。

Another way could be: Try to get all child threads of the main process and do something like 另一种方法可能是:尝试获取主进程的所有子线程,然后执行类似的操作

Thread t1; // specific child thread 
t1.join(); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM