我正在使用C#和WPF在Visual Studio 2015上开发一个项目。有时我使用close命令退出运行项目,有时使用stop debug按钮退出。问题是经过几次测试后,我的电脑开始变热,风扇发出噪音。我必须退出Visual Studio才能让机器平静下来。
所以我有疑问:
Dispose
)WindowClosing
个线程
谢谢
编辑:
有任务管理器的屏幕截图。当我开始应用时,CPU从5%上升到15%(或事件25%)。 RAM从4GO上升到4.5。 当我停止应用程序时,CPU会在几秒内达到45%并返回到5%但RAM会变为4.70GO并且不会再下降。
EDIT2:
我在我的应用程序中创建了这种线程:
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 */
}
我想知道是否有一个非常好的方法来使用线程?如果应用程序关闭但未设置isClosing = true
,则永远不会停止。线程永远不会真正中止?你认为这种线程会导致我遇到的所有麻烦吗?
答案 0 :(得分:0)
这是my solution如何以优雅的方式停止线程。希望代码清楚。我使用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();
}
}
}
答案 1 :(得分:-1)
也许您可以尝试使用“Process Hacker”工具观察流程和线程的行为。使用此工具可以获得有关线程的更多详细信息,还可以检测deamon线程。
另一种方法可能是:尝试获取主进程的所有子线程并执行类似
的操作Thread t1; // specific child thread
t1.join();