• 如何在在WinFrom的DataGridView中做到数据持续动态加载而不卡死


    1.在这个过程我用过好几种办法

    (1)使用委托的办法,这个方法可以做到持续加载,但是效果不理想会卡死

    (2)开启线程的方法,会造成卡死

    (3)使用另一个窗体的线程做持续加载(子窗体),让子窗体作为一个中间件去通知dataGridView绑定数据,子窗体隐藏。从而可以使主窗体不用卡死 ,给用户造成一中假状态,卡死的是子窗体而已,并且做了隐藏。

    2.截图如下

    (3)代码如下

    <1>借助了两个类:ComAsyncExecute.cs  TSwitch.cs

    <2>具体代码内容如下:

    ComAsyncExecute.cs

    using System;
    using System.Threading;
    using System.Windows.Forms;

    namespace APIBigData.Helper.Tool
    {

    public class ComEventArgsBase
    {
    public Exception Error = null;
    }
    public class ComEventArgs<T> : ComEventArgsBase
    {
    public String ErrorInfo = "";
    public T Result
    {
    get;
    set;
    }
    }

    public class ComEventArgs<T, TM> : ComEventArgs<T>
    {
    public TM Per1 = default(TM);
    public ComEventArgs(TM per)
    {
    this.Per1 = per;
    }

    }

    public class ComEventArgs<T, TM, TZ> : ComEventArgs<T, TM>
    {
    public TZ Per2 = default(TZ);
    public ComEventArgs(TM per, TZ per2)
    : base(per)
    {
    this.Per2 = per2;
    }

    }


    public class ComAsyncOnceDrive
    {
    private void SetDataSource(Object ob, EexecuteState estare)
    {
    if (delSetData != null) { delSetData(ob, estare); }
    }
    private void SetDataSourceExtract(Object ob, EexecuteState estare)
    {
    if (delSetDataExtract != null) { delSetDataExtract(ob, estare); }
    }
    public TSwitch.Omnipotent<Object, EexecuteState> delSetData = null;
    public TSwitch.Omnipotent<Object, EexecuteState> delSetDataExtract = null;
    }
    public enum EexecuteState : int
    {
    Start = 0,
    Middle = 1,
    End = 3,
    }

    /// <summary>
    /// 通用异步工具
    /// </summary>
    /// <typeparam name="T"></typeparam>

    public class ComAsync<T> where T : ComEventArgsBase
    {
    public delegate void CellProcedureArray(T ob);
    private ComAsyncOnceDrive _onceder = null;
    public ComAsyncOnceDrive GetOnceControl()
    {
    var z = new ComAsyncOnceDrive
    {
    delSetData = (e, m) =>
    {
    if (FinshOneceEexecute != null && _puiThread != null)
    {
    _puiThread.BeginInvoke(FinshOneceEexecute, new object[] { e, m });
    }
    }
    };
    this._onceder = z;

    return z;

    }
    public ComAsyncOnceDrive GetOnceControlExtract()
    {
    var z = new ComAsyncOnceDrive
    {
    delSetDataExtract = (e, m) =>
    {
    if (FinshOneceEexecuteExtract != null && _puiThread != null)
    {
    _puiThread.BeginInvoke(FinshOneceEexecuteExtract, new object[] { e, m });
    }
    }
    };
    this._onceder = z;
    return z;

    }

    CellProcedureArray _cellprocedureArrayAsync = null;
    public delegate void DelcellFinsh(object sender, T e);
    public DelcellFinsh EnevtcellFinsh = null;
    public TSwitch.Omnipotent<Object, EexecuteState> FinshOneceEexecute = null;
    public TSwitch.Omnipotent<Object, EexecuteState> FinshOneceEexecuteExtract = null;
    private readonly Form _puiThread = null;
    private T _data = null;
    public ComAsync(Form fo)
    {
    _puiThread = fo;
    }
    public IAsyncResult AsynResult = null;
    public bool IsUIfinsh
    {
    get { return AsynResult != null && AsynResult.IsCompleted; }

    }
    public ComAsync() { }
    public void BindProcedure(T t, CellProcedureArray cell)
    {
    BindProcedure(cell, t);
    }
    public void BindProcedure(CellProcedureArray cell, T t)
    {
    if (_cellprocedureArrayAsync == null)
    {
    _cellprocedureArrayAsync = new CellProcedureArray(cell);
    _data = t;
    }
    else
    {
    _cellprocedureArrayAsync = null;
    _cellprocedureArrayAsync = new CellProcedureArray(cell);
    _data = t;

    }

    }
    //可用
    public bool IsWiatUse
    {
    get { return !_isRun; }
    }

    private bool _isRun = false;
    public void Run()
    {
    if (_isRun == false)
    {
    ThreadPool.QueueUserWorkItem(new WaitCallback(RunProcedure), 0);
    _isRun = true;
    }
    else
    {
    throw new Exception("客官别急,正在努力加载中");
    }
    }

    public void RunProcedure(object ob)
    {
    AsynResult = null;
    if (_cellprocedureArrayAsync == null) { throw new Exception("没有绑定函数,无法运行"); }

    try
    {
    //执行
    if (_cellprocedureArrayAsync != null) { _cellprocedureArrayAsync.Invoke(_data); }
    }
    catch (Exception ex)
    {
    _data.Error = ex;
    }
    //回调

    //如果是UI线程
    if (_puiThread != null && EnevtcellFinsh != null)
    {
    _puiThread.BeginInvoke(EnevtcellFinsh, new object[] { this, _data });
    }
    else
    {
    // ThreadPool.QueueUserWorkItem(new WaitCallback(CellNewThind), new ComEventArgs<T>(t, exTemp, RefParameter));
    if (EnevtcellFinsh != null) { EnevtcellFinsh.Invoke(this, _data); }
    }
    // timeEnd = DateTime.Now;
    _isRun = false;
    }
    private void CellNewThind(object ob)
    {


    }

    }


    }

     TSwitch.cs

    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;

    namespace APIBigData.Helper.Tool
    {

    /// <summary>
    /// T类型和M类型的转换 或者 T与object 之间的转换,并提供了万能模板事件
    /// </summary>
    public class TSwitch
    {
    /// <summary>
    /// 通用模板事件
    /// </summary>
    /// <typeparam name="A"></typeparam>
    /// <param name="t"></param>
    public delegate void Omnipotent<A >(A t);
    public delegate void Omnipotent<A, B>(A t, B m);
    public delegate void Omnipotent<A, B, C>(A t, B m, C z);
    public delegate void Omnipotent<A, B, C,D>(A t, B m, C z,D d);
    public delegate void Omnipotent<A, B, C, D, E>(A t, B m, C z, D d ,E e);
    public delegate void Omnipotent<A, B, C, D, E, F>(A t, B m, C z, D d, E e ,F f);

    public delegate Object OmnipotentTo<A>(A t);
    public delegate Object OmnipotentTo<A, B>(A t, B m);
    public delegate Object OmnipotentTo<A, B, C>(A t, B m, C z);
    public delegate Object OmnipotentTo<A, B, C, D>(A t, B m, C z, D d);
    public delegate Object OmnipotentTo<A, B, C, D, E>(A t, B m, C z, D d, E e);
    public delegate Object OmnipotentTo<A, B, C, D, E, F>(A t, B m, C z, D d, E e, F f);

    public delegate bool OmnipotentDispose<A>(A t);
    public delegate bool OmnipotentDispose<A, B>(A t, B m);
    public delegate bool OmnipotentDispose<A, B, C>(A t, B m, C z);
    public delegate bool OmnipotentDispose<A, B, C, D>(A t, B m, C z, D d);
    public delegate bool OmnipotentDispose<A, B, C, D, E>(A t, B m, C z, D d, E e);
    public delegate bool OmnipotentDispose<A, B, C, D, E, F>(A t, B m, C z, D d, E e, F f);

    /// <summary>
    /// 模板类型数组转换 T --> M
    /// </summary>
    /// <typeparam name="T">源类型</typeparam>
    /// <typeparam name="M">目标类型</typeparam>
    /// <param name="source">源数据 T</param>
    /// <param name="TypeTransition">转换事件</param>
    /// <returns>目标类型M</returns>
    public static M TTransitionT<T,M>(T source , OmnipotentTo<T> TypeTransition)
    {
    return (M)TypeTransition(source);
    }

    /// <summary>
    /// 模板类型数组转换 T[] --> M[]
    /// </summary>
    /// <typeparam name="T">源类型</typeparam>
    /// <typeparam name="M">目标类型</typeparam>
    /// <param name="source">源数据数组 T[]</param>
    /// <param name="TypeTransition">转换事件</param>
    /// <returns>目标类型数组 M[]</returns>
    public static M[] TTransitionT<T, M>(T[] source, OmnipotentTo<T> TypeTransition)
    {
    M[] Datasz = new M[source.Count()];

    int i = 0;
    foreach (T t in source)
    {
    Datasz[i] = TTransitionT<T, M>(t, TypeTransition);
    i++;
    }

    return Datasz;
    }

    /// <summary>
    /// 模板类型数组转换 T[] --> Object[]
    /// </summary>
    /// <typeparam name="T">被转换的类型</typeparam>
    /// <param name="ts">参数数组 ,T[]</param>
    /// <returns>object数组</returns>
    public static object[] ObsTransition<T>(T[] ts)
    {
    List<object> obs = new List<object>();
    foreach (T t in ts)
    {
    obs.Add(t);
    }
    return obs.ToArray();
    }


    /// <summary>
    /// 模板类型数组转换 Object[] --> T[]
    /// </summary>
    /// <typeparam name="T">想要输出的类型</typeparam>
    /// <param name="obs">参数数组 ,Object[]</param>
    /// <returns>T[]输出的数组</returns>
    public static T[] TsTransition<T>(Object[] obs)
    {
    List<T> ts = new List<T>();
    foreach (object ob in obs)
    {
    ts.Add((T)ob);
    }
    return ts.ToArray();

    }

    public static T[] TsTransition<T>(IList list)
    {
    T[] ts = new T[list.Count];
    for(int i = 0; i <list.Count;i++)
    {
    ts[i] = (T)list[i];
    }

    return ts;

    }

    /// <summary>
    /// 万能数据筛选/处理, 事件返回值等于 true 则添加
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="ts"></param>
    /// <param name="delT"></param>
    /// <returns></returns>
    public static T[] DataDispose<T>(T[] ts, OmnipotentDispose<T> delT)
    {
    if(ts == null) {return null;}

    List<T> listT = new List<T>();
    for (int i = 0; i < ts.Length; i++)
    {
    if (delT(ts[i])) { listT.Add(ts[i]); }
    }

    return listT.ToArray();
    }


    /// <summary>
    /// 万能数据筛选
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="ts"></param>
    /// <param name="delT"></param>
    /// <returns></returns>
    public static T[] DataDispose<T>(T[] ts, Omnipotent<T> delT)
    {
    if (ts == null) { return null; }

    List<T> listT = new List<T>();
    for (int i = 0; i < ts.Length; i++)
    {
    listT.Add(ts[i]);
    }

    return listT.ToArray();
    }
    }
    }

    查询事件下的代码:  调用Serarch()

    private Waiting _wait = null;
    //原来调用具有返回值的方法的声明
    // private ComAsync<ComEventArgs<List<Website>, QueryCriteria>> _comGetSearchWork = null;
    private ComAsync<ComEventArgsBase> _comGetSearchWork = null;
    public void Search(QueryCriteria query)
    {
    //原来调用具有返回值方法的判断
    // if (_comGetSearchWork == null) { _comGetSearchWork = new ComAsync<ComEventArgs<List<Website>, QueryCriteria>>(this); }
    if (_comGetSearchWork == null) { _comGetSearchWork = new ComAsync<ComEventArgsBase>(this); }
    this.dataGridView.Rows.Clear();
    this.dataGridViewExtract.Rows.Clear();
    if (checkLog.CheckState == CheckState.Checked)
    email = new ExtractEmail(query, new XmlHelper(DateTime.Now), new DataBindGridView(DataBind));
    else email = new ExtractEmail(query, null, new DataBindGridView(DataBind));
    //ExtractEmail email = new ExtractEmail(query, new XmlHelper(), new DataBindGridView(DataBind));

    email.dri = _comGetSearchWork.GetOnceControl();
    email.driExtract = _comGetSearchWork.GetOnceControlExtract();

    //原来调用有返回值的方法
    //_comGetSearchWork.BindProcedure(new ComEventArgs<List<Website>, QueryCriteria>(query), ob =>
    //{

    // ob.Result=email.Result_Email();

    //});
    _comGetSearchWork.BindProcedure(new ComEventArgsBase(), ob =>
    {

    email.Result_Emails();

    });

    _comGetSearchWork.FinshOneceEexecute = (e, m) =>
    {
    Website data = e as Website;

    //这个方法是操作dataGrivdView的方法 有数据绑定 显示指定列  根据需求具体操作
    DataBind(new List<Website>(new Website[] { data }));
    };

    _comGetSearchWork.FinshOneceEexecuteExtract = (e, m) =>
    {
    Website data = e as Website;

    //这个方法是操作dataGrivdView的方法 有数据绑定 显示指定列根据需求具体操作

    DataBindExtract(new List<Website>(new Website[] { data }));


    };
    _comGetSearchWork.EnevtcellFinsh = (sen, e) =>
    {
    try
    {
    if (e.Error != null)
    {
    //执行错误
    _wait.Close();

    MessageBox.Show(e.Error.Message);
    return;
    }
    }
    catch (Exception)
    {

    // throw;
    }
    finally
    {
    _wait.Close();
    this.btnSearchClick.Enabled = true;
    if (this.dataGridView.Rows.Count > 0) this.btnExportExcel.Enabled = true;
    //SetGridView();
    // string time = ThanTime(timeStart, _comGetSearchWork.timeEnd);
    MessageBox.Show("查询完毕", "温馨提示");
    this.searchLab.Text = "搜索完成";
    this.pos = 0;
    }

    };


    _wait = new Waiting();
    _comGetSearchWork.Run();
    // Location = new Point(_wait.Location.X-Size.Width, _wait.Location.Y - Size.Height);
    // _wait.ShowDialog();
    _wait.MdiParent = this;
    _wait.StartPosition = FormStartPosition.CenterScreen;
    _wait.Show();
    _wait.Hide();

    }

    操作数据类:

    在这个类中我们首先要声明一个:

    然后添加:

    这里我是把一个集合通过他绑定到dataGridView

    最后附一张图片,是关键代码,具体的用法研究下,如有不对,还希望大家指正

    至此整个过程完成 ,这个方法我也是从大神那里得到的 .感谢帮助我各位,在这里我做一个总结,由于涉及到保密,未能过完整提供源码。

  • 相关阅读:
    logback学习二
    logback学习
    弱类型、强类型、动态类型、静态类型语言的区别
    BlockingQueue
    ExecutorService
    Future学习
    SetTimeout()多次运行函数后越来越快的问题
    LISTAGG函数
    Oracle字段
    使用powerdesigner进行数据库设计
  • 原文地址:https://www.cnblogs.com/RainbowFife/p/5563892.html
Copyright © 2020-2023  润新知