我正在探索C#WinForms中的线程实现,我创建了这个简单的应用程序:
我只是想知道为什么在我启动,停止,启动和再次停止应用程序后,此应用程序的内存使用量不断增长.当我按下停止按钮时,我想到我的线程实例没有真正终止或中止.请考虑下面的代码,我们将非常感谢您提供任何帮助或建议.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace ThreadingTest
{
public partial class Form1 : Form
{
private delegate void TickerDelegate(string s);
bool stopThread = false;
TickerDelegate tickerDelegate1;
Thread thread1;
public Form1()
{
InitializeComponent();
tickerDelegate1 = new TickerDelegate(SetLeftTicker);
}
private void Form1_Load(object sender, EventArgs e)
{
thread1 = new Thread(new ThreadStart(disp));
thread1.Start();
}
void disp()
{
while (stopThread == false)
{
listBox1.Invoke(tickerDelegate1, new object[] { DateTime.Now.ToString() });
Thread.Sleep(1000);
}
}
private void SetLeftTicker(string s)
{
listBox1.Items.Add(s);
}
private void btnStop_Click(object sender, EventArgs e)
{
stopThread = true;
if (thread1.IsAlive)
{
thread1.Abort();
}
}
private void btnStart_Click(object sender, EventArgs e)
{
stopThread = false;
thread1 = new Thread(new ThreadStart(disp));
thread1.Start();
}
private void btnCheck_Click(object sender, EventArgs e)
{
if (thread1.IsAlive)
{
MessageBox.Show("Is Alive!");
}
}
private void btnClear_Click(object sender, EventArgs e)
{
listBox1.Items.Clear();
}
}
}
Run Code Online (Sandbox Code Playgroud)
好的,有几条建议:
让你的旗帜变得不稳定......如果你不这样做,那么线程永远不会看到对旗帜的更新.
volatile bool stopThread = false;
Run Code Online (Sandbox Code Playgroud)
将该IsBackground属性设置为true:如果应用程序退出,它会强制终止该线程,否则即使在应用程序关闭后,您也可能会出现"ghost线程".
thread1.IsBackground = true;
thread1.Start();
Run Code Online (Sandbox Code Playgroud)
如果线程刚刚开始睡眠,那么即使在它有机会阅读标志之前你也会中止它...此外你不想使用Abort因为:
...如果一个线程在另一个线程上调用Abort,则中止将中断正在运行的任何代码.当finally块正在运行时,线程有可能中止,在这种情况下,finally块被中止.静态构造函数也有可能被中止.在极少数情况下,这可能会阻止在该应用程序域中创建该类的实例.
因此,我建议您调用Interrupt并处理线程内的异常,而不是使用abort :
private void btnStop_Click(object sender, EventArgs e)
{
// have another method for re-use
StopThread();
}
private void StopThread()
{
stopThread = true;
// the time out is 100 ms longer than the thread sleep
thread1.Join(1100);
// if the thread is still alive, then interrupt it
if(thread1.IsAlive)
{
thread1.Interrupt();
}
}
Run Code Online (Sandbox Code Playgroud)
每次单击"开始"按钮时都会泄漏线程...如果thread1已经分配了一个线程并且您为其分配了另一个线程,则前一个线程将继续存在.您需要在启动另一个线程之前停止前一个线程.
private void btnStart_Click(object sender, EventArgs e)
{
// stop the previous thread
StopThread();
// create a new thread
stopThread = false;
thread1 = new Thread(new ThreadStart(disp));
thread1.IsBackground = true;// set it to background again
thread1.Start();
}
Run Code Online (Sandbox Code Playgroud)
最后,您需要处理线程中的中断:
void disp()
{
try
{
while (stopThread == false)
{
listBox1.Invoke(tickerDelegate1, new object[] { DateTime.Now.ToString() });
Thread.Sleep(1000);
}
}
catch(ThreadInterruptedException)
{
// ignore the exception since the thread should terminate
}
}
Run Code Online (Sandbox Code Playgroud)
我认为这就是它......哦......实际上,还有一件事:线程谨慎!;)
| 归档时间: |
|
| 查看次数: |
1168 次 |
| 最近记录: |