编程之路

——火地晋

  :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  291 随笔 :: 2 文章 :: 297 评论 :: 134万 阅读

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;
    }));
}
复制代码

 

 

用到的测试类

 

复制代码
public delegate void CommonDelegate();
public class ThreadTest
{
    
public ThreadTest() {  }
    
public int GetRandomNum()
    {
        Random rd 
= new Random();
        
return rd.Next(110);
    }
}
复制代码

 

调用按钮事件

 

 

复制代码
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(
"");
}
复制代码

 

 

测试源码https://files.cnblogs.com/yelaiju/WinFormSynTest.rar

posted on   火地晋  阅读(5758)  评论(20编辑  收藏  举报
编辑推荐:
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
阅读排行:
· 单线程的Redis速度为什么快?
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 展开说说关于C#中ORM框架的用法!
· SQL Server 2025 AI相关能力初探
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
点击右上角即可分享
微信分享提示