我在桌面编程时想实现多线程
是这样的:
我窗体左边是个TreeView控件,右边是DataGrid
当我点击树形节点时,根据节点参数从数据库中读取数据填充在
DataGrid中,当数据量很大时窗体没反应,我想用多线程,请问怎么解决
窗体假死状态。  private void TreeView_AfterSelect(object sender, TreeViewEventArgs e)
        {           
             DataSet thds = new DataSet(); 
    thds = LoadData("select * From theTable");//读取数据的类            FullCell FilC = new FullCell();//填充Grid的类     
      FilC.FillCellTable(thds);         }

解决方案 »

  1.   

    先写一个方法,将读取数据和填充Grid过程放入其中,然后在TreeView_AfterSelect方法中使用线程异步调用该方法。
    MethodInvoker mi = new MethodInvoker(DoMyJob);
    mi.BeginInvoke(null, null);//DoMyJob为无参数、无返回值类型方法
      

  2.   


    /// <summary>
            /// POS字体样式
            /// </summary>
            /// 
            public uint  POS_FONT_TYPE_STANDARD  = 0x00;// 标准 ASCII 
            public uint  POS_FONT_TYPE_COMPRESSED = 0x01;// 压缩 ASCII  
            public uint  POS_FONT_TYPE_UDC = 0x02;       // 用户自定义字符 
            public uint  POS_FONT_TYPE_CHINESE = 0x03;   // 标准 “宋体” 
            public uint  POS_FONT_STYLE_NORMAL =  0x00;   //  正常 
            public uint  POS_FONT_STYLE_BOLD =  0x08;   //  加粗 
            public uint  POS_FONT_STYLE_THIN_UNDERLINE =  0x80;   //  1点粗的下划线 
            public uint  POS_FONT_STYLE_THICK_UNDERLINE =  0x100;   //  2点粗的下划线 
            public uint  POS_FONT_STYLE_UPSIDEDOWN =  0x200;   //  倒置(只在行首有效) 
            public uint  POS_FONT_STYLE_REVERSE =  0x400;   //  反显(黑底白字) 
            public uint  POS_FONT_STYLE_SMOOTH =  0x800;   //  平滑处理(用于放大时) 
            public uint POS_FONT_STYLE_CLOCKWISE_90 = 0x1000;   //  每个字符顺时针旋转 90 度        /// <summary>
            /// 把将要打印的字符串数据发送到打印缓冲区中,并指定X 方向(水平)上的绝对起始点位置,
            /// 指定每个字符宽度和高度方向上的放大倍数、类型和风格。
            /// </summary>
            /// <param name="pszString">指向以 null 结尾的字符串缓冲区</param>
            /// <param name="nOrgx">指定 X 方向(水平)的起始点位置离左边界的点数。</param>
            /// <param name="nWidthTimes">指定字符的宽度方向上的放大倍数。可以为 1到 6。</param>
            /// <param name="nHeightTimes">指定字符高度方向上的放大倍数。可以为 1 到 6。</param>
            /// <param name="nFontType">指定字符的字体类型。</param>
            /// <param name="nFontStyle">指定字符的字体风格。</param>
            /// <returns></returns>
            
            [DllImport("POSDLL.dll", SetLastError = true)]
            public static extern IntPtr POS_S_TextOut([MarshalAs(UnmanagedType.LPStr)]string pszString, 
                                                       uint nOrgx, uint nWidthTimes, uint nHeightTimes, 
                                                       uint nFontType, uint nFontStyle);        /// <summary>
            /// 设置POS的打印模式 (只有两种 页模式和标准模式)
            /// </summary>
            /// <param name="nPrintMode">
            /// POS_PRINT_MODE_STANDARD 0x00 标准模式(行模式) 
            /// POS_PRINT_MODE_PAGE 0x01 页模式 
            /// POS_PRINT_MODE_BLACK_MARK_LABEL 0x02 黑标记标签模式 
            /// POS_PRINT_MODE_WHITE_MARK_LABEL 0x03 白标记标签模式 </param>
            /// <returns></returns>
            [DllImport("POSDLL.dll", SetLastError = true)]
            public static extern IntPtr POS_SetMode(uint nPrintMode);
            /// <summary>
            /// 设置字符的行高。
            /// </summary>
            /// <param name="nDistance">指定行高点数。可以为 0 到 255。每点的距离与打印头分辨率相关。</param>
            /// <returns></returns>
            [DllImport("POSDLL.dll", SetLastError = true)]
            public static extern IntPtr POS_SetLineSpacing(uint nDistance);
            /// <summary>
            /// 设置字符的右间距(相邻两个字符的间隙距离)。
            /// </summary>
            /// <param name="nDistance">指定右间距的点数。可以为 0 到 255。每点的距离与打印头分辨率相关。</param>
            /// <returns></returns>
            [DllImport("POSDLL.dll", SetLastError = true)]
            public static extern IntPtr POS_SetRightSpacing(int nDistance);
      

  3.   

    private void TreeView_AfterSelect(object sender, TreeViewEventArgs e)
      {    
    thread th=new thread(new ParameterizedThreadStart(test));
    th.start(参数);
      }test(object obj)
    {
      DataSet thds = new DataSet();  
    thds = LoadData("select * From theTable");//读取数据的类  FullCell FilC = new FullCell();//填充Grid的类   
      FilC.FillCellTable(thds);
    }
      

  4.   

    谢谢一楼,再问问 意思是多线程只能执行void 的过程吗?
      

  5.   

    然后,又涉及到一个问题:如何在一个辅助线程中访问主窗体的控件?
    解决办法:再写一个填充Grid的方法,参数是数据库返回的结果,假设名称为FillGrid,在DoMyJob方法中采用如下方法调用:
    object[] pList = { this, EventArgs.Empty };
    Grid.BeginInvoke(new EventHandler(FillGrid), pList);
      

  6.   

    不是,void的过程使用起来简单啦
      

  7.   

    先写一个方法,将读取数据和填充Grid过程放入其中,然后在TreeView_AfterSelect方法中使用线程异步调用该方法。
    MethodInvoker mi = new MethodInvoker(DoMyJob);
    mi.BeginInvoke(null, null);//DoMyJob为无参数、无返回值类型方法然后,又涉及到一个问题:如何在一个辅助线程中访问主窗体的控件?
    解决办法:再写一个填充Grid的方法,参数是数据库返回的结果,假设名称为FillGrid,在DoMyJob方法中采用如下方法调用:
    object[] pList = { this, EventArgs.Empty };
    Grid.BeginInvoke(new EventHandler(FillGrid), pList);对于这个问题,上周我花了两天时间才搞定,比较费解。
    建议参考:http://blog.csdn.net/sheshou2/archive/2010/01/19/5212171.aspx
      

  8.   

    数据库做索引,确保有主键,优化表,优化SQL语句