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
最后附一張圖片,是關鍵代碼,具體的用法研究下,如有不對,還希望大家指正
至此整個過程完成 ,這個方法我也是從大神那里得到的 .感謝幫助我各位,在這里我做一個總結,由於涉及到保密,未能過完整提供源碼。