2013-07-10
卡住很有可能是因为在窗体的Invoke里进行了大量运算。
一般情况,在线程中就仅仅进行和窗体无关的计算,必要时,使用Invoke进行一些窗体状态的更新,这样完全不会导致卡住冻结。
2010-09-25 18:57更新:根据各位朋友的回复,做了一些更新。
加入了BackgroundWorker和MethodInvoker
有时候我们在窗体的执行方法中,会延迟很久,那样就会造成操作窗体(界面)卡住(冻结)的情况出现,这样的用户体验非常糟糕。
在使用线程操作,则可能会避免这种情况。
因此我做了一个测试。
在这方面的设计,我也是初学者,因此,有不对的地方,请前辈指点迷津。
/// <summary>
/// 执行的主逻辑
/// </summary>
/// <param name="obj"></param>
private void RunMethod(object obj)
{
ThreadTest tt = new ThreadTest();
int curValue = 0;
for (int i = 0; i < 20; i++)
{
curValue = tt.GetRandomNum();
//不添加5的项,主要为了添加业务复杂性
while (curValue == 5)
{
Thread.Sleep(2000);//制造延迟,测试是否会冻结(卡)主窗口
curValue = tt.GetRandomNum();
}
Thread.Sleep(2000);//制造延迟,测试是否会冻结(卡)主窗口
if (this.InvokeRequired)
{
this.Invoke(new MethodInvoker(delegate()
{
this.lsbShow.Items.Add(curValue);
this.lsbShow.SelectedIndex = lsbShow.Items.Count - 1;
}));
}
else
{
lsbShow.Items.Add(curValue);
}
}
this.Invoke(new MethodInvoker(delegate()
{
this.btnRun.Enabled = true;
this.btnThread.Enabled = true;
btnBackgroundWorker.Enabled = true;
this.lsbShow.Items.Add("Done");
this.lsbShow.SelectedIndex = lsbShow.Items.Count - 1;
}));
}
/// 执行的主逻辑
/// </summary>
/// <param name="obj"></param>
private void RunMethod(object obj)
{
ThreadTest tt = new ThreadTest();
int curValue = 0;
for (int i = 0; i < 20; i++)
{
curValue = tt.GetRandomNum();
//不添加5的项,主要为了添加业务复杂性
while (curValue == 5)
{
Thread.Sleep(2000);//制造延迟,测试是否会冻结(卡)主窗口
curValue = tt.GetRandomNum();
}
Thread.Sleep(2000);//制造延迟,测试是否会冻结(卡)主窗口
if (this.InvokeRequired)
{
this.Invoke(new MethodInvoker(delegate()
{
this.lsbShow.Items.Add(curValue);
this.lsbShow.SelectedIndex = lsbShow.Items.Count - 1;
}));
}
else
{
lsbShow.Items.Add(curValue);
}
}
this.Invoke(new MethodInvoker(delegate()
{
this.btnRun.Enabled = true;
this.btnThread.Enabled = true;
btnBackgroundWorker.Enabled = true;
this.lsbShow.Items.Add("Done");
this.lsbShow.SelectedIndex = lsbShow.Items.Count - 1;
}));
}
用到的测试类
public delegate void CommonDelegate();
public class ThreadTest
{
public ThreadTest() { }
public int GetRandomNum()
{
Random rd = new Random();
return rd.Next(1, 10);
}
}
public class ThreadTest
{
public ThreadTest() { }
public int GetRandomNum()
{
Random rd = new Random();
return rd.Next(1, 10);
}
}
调用按钮事件
private void btnRun_Click(object sender, EventArgs e)
{
RunStart();
ThreadPool.QueueUserWorkItem(new WaitCallback(RunMethod));
}
private void btnThread_Click(object sender, EventArgs e)
{
RunStart();
Thread td = new Thread(new ParameterizedThreadStart(RunMethod));
td.Start("");
}
private void RunStart()
{
lsbShow.Items.Clear();
btnRun.Enabled = false;
btnThread.Enabled = false;
btnBackgroundWorker.Enabled = false;
}
private void btnBackgroundWorker_Click(object sender, EventArgs e)
{
RunStart();
using (BackgroundWorker bw = new BackgroundWorker())
{
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.RunWorkerAsync();
}
}
void bw_DoWork(object sender, DoWorkEventArgs e)
{
RunMethod("");
}
{
RunStart();
ThreadPool.QueueUserWorkItem(new WaitCallback(RunMethod));
}
private void btnThread_Click(object sender, EventArgs e)
{
RunStart();
Thread td = new Thread(new ParameterizedThreadStart(RunMethod));
td.Start("");
}
private void RunStart()
{
lsbShow.Items.Clear();
btnRun.Enabled = false;
btnThread.Enabled = false;
btnBackgroundWorker.Enabled = false;
}
private void btnBackgroundWorker_Click(object sender, EventArgs e)
{
RunStart();
using (BackgroundWorker bw = new BackgroundWorker())
{
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.RunWorkerAsync();
}
}
void bw_DoWork(object sender, DoWorkEventArgs e)
{
RunMethod("");
}
作者:
火地晋
出处: http://yelaiju.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
出处: http://yelaiju.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 单线程的Redis速度为什么快?
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 展开说说关于C#中ORM框架的用法!
· SQL Server 2025 AI相关能力初探
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库