zoukankan      html  css  js  c++  java
  • 线程与WinForm设计,防冻结,卡住窗体

    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

    作者: 火地晋
    出处: http://yelaiju.cnblogs.com
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    BZOJ 1726: [Usaco2006 Nov]Roadblocks第二短路
    BZOJ 1708: [Usaco2007 Oct]Money奶牛的硬币
    BZOJ 1642: [Usaco2007 Nov]Milking Time 挤奶时间
    BZOJ 1611: [Usaco2008 Feb]Meteor Shower流星雨
    BZOJ 1610: [Usaco2008 Feb]Line连线游戏
    BZOJ 1609: [Usaco2008 Feb]Eating Together麻烦的聚餐
    BZOJ 1607: [Usaco2008 Dec]Patting Heads 轻拍牛头
    BZOJ 1606: [Usaco2008 Dec]Hay For Sale 购买干草
    BZOJ 1083: [SCOI2005]繁忙的都市
    STL set的用法
  • 原文地址:https://www.cnblogs.com/yelaiju/p/1834266.html
Copyright © 2011-2022 走看看