如何在在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

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

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

时间: 2024-09-29 23:53:43

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

Android中插件开发篇之----动态加载Activity(免安装运行程序)

一.前言 又到周末了,时间过的很快,今天我们来看一下Android中插件开发篇的最后一篇文章的内容:动态加载Activity(免安装运行程序),在上一篇文章中说道了,如何动态加载资源(应用换肤原理解析),没看过的同学,可以转战: http://blog.csdn.NET/jiangwei0910410003/article/details/47679843 当然,今天说道的内容还这这篇文章有关系.关于动态加载Activity的内容,网上也是有很多文章介绍了.但是他们可能大部分都是介绍通过代理的方

element中树形数据与懒加载实现全部展开和全部收起

element中属性懒加载数据 default-expand-all属性::是否默认展开所有行,当 Table 包含展开行存在或者为树形表格时有效 如果在表格头上加上一个按钮实现全部展开与收起 类似如图这种  默认是[全部展开]按钮,点击后,树状列表下所有数据为展示,按钮变为[全部收起]:点击[全部收起]时,树状列表下所有数据为收起状态,即返回默认状 如果动态设置控制default-expand-all树状图是不发生变化的 也就是不起作用. 解决方法:上代码: <template> <d

Android中apk动态加载技术研究(2)android插件化及实现

了解了android中类加载的前期知识点后,来看看android中DexClassLoader具体的实现 具体加载流程如下: 宿主程序会到文件系统比如SD卡中去加载APK[1],然后通过一个叫proxy的Activity去执行apk中的Activity 关于动态加载ap,理论上可用用到DexClassLoad.PathClassLoader.URLClassLoader; DexClassLoader: 可以加载文件系统上的jar.dex.apk PathClassLoader:可以加载 /da

vs 2015 rdlc报表绑定datagridview中的数据

这几天一直想要实现rdlc报表绑定datagridview中的数据,始终在虚拟表向rdlc报表绑定这一步上出错.今天从下午4点到七点四十一直在尝试.最终还是实现了,最然并不知所以然,这个问题还是以后在考虑吧,目前的项目要紧. 首先是  datagridview中的数据传到虚拟表中. for (int i = 0; i < dgvscan.Columns.Count - 1; i++) { dtout.Columns.Add(dgvscan.Columns[i].Name); } //添加行 fo

c#.net循环将DataGridView中的数据赋值到Excel中,并设置样式

Microsoft.Office.Interop.Excel.Application excel =                new Microsoft.Office.Interop.Excel.Application();            excel.SheetsInNewWorkbook = 1;            excel.Workbooks.Add(); //设置Excel列名            excel.Cells[1, 1] = "学号";     

C#读取Excel表格数据到DataGridView中和导出DataGridView中的数据到Excel

其实想在datagridview中显示excel表格中的数据跟读取数据库中的数据没什么差别,只不过是创建数据库连接的时候连接字段稍有差别. private void btnShow_Click(object sender, EventArgs e) { OpenFileDialog fd = new OpenFileDialog();//首先根据打开文件对话框,选择excel表格 ofd.Filter = "表格|*.xls";//打开文件对话框筛选器 string strPath;/

Java中动态加载jar文件和class文件

概述 诸如tomcat这样的服务器,在启动的时候会加载应用程序中lib目录下的jar文件以及classes目录下的class文件,另外像spring这类框架,也可以根据指定的路径扫描并加载指定的类文件,这个技术可以实现一个容器,容纳各类不同的子应用. Java类由于需要加载和编译字节码,动态加载class文件较为麻烦,不像C加载动态链接库只要一个文件名就可以搞定,但JDK仍提供了一整套方法来动态加载jar文件和class文件. 动态加载jar文件 // 系统类库路径 File libPath =

unity3D中动态加载物体的常用的方法

1.用Resources.Load():参数为路径,需要在Assets文件夹中创建Resources文件夹,通过路径去查找,实例化并加入到内存中去,通过Instantiate动态加载的方法来实现物体场景的加载: 2.使用AssetBundle打包预设或者场景可以将与其相关的所有资源打包,这样很好地解决资源的依赖问题 要先打包资源: using UnityEngine;using System.Collections;using UnityEditor;using System.IO;public

使用custombox和动态加载的分部视图中tooltip无效,或者tooltip看不到

首先MVC中动态加载的分部视图,需要在这个分部视图的View页面最后执行下这个函数 <script>    $("[data-toggle='tooltip']").tooltip(); //重新开启下tooltip</script> 就可以正常了 tooltip的z-index时候1070 bootstrap的modal时候1050,直接使用bootstrap的弹出框时候,tooltip是完全正常的 不过custombox的z-index达到9999 这个需要