首先自己添加一个窗体制作一个等待窗体
我的是gif动图,赖得写代码了
我是用Action方法做的,Func做法差不多就不介绍了
还有一种方法用async/await实现
值得一说的是在.net 5版本以后BeginInvoke不能用了,所以用async/await,这里我们来简单封装。如下:
/// <summary>
/// 异步加载数据并且弹出等待窗体
/// </summary>
/// <param name="action"></param>
protected void LoadData(Action action)
{
if (action == null)
return;
using (FmLoading fl = new FmLoading())
{
LoadDataAsync(action, fl);
fl.ShowDialog();
}
}
/// <summary>
/// 异步方法
/// </summary>
/// <param name="action"></param>
/// <param name="fl"></param>
/// <returns></returns>
private async Task LoadDataAsync(Action action, FmLoading fl)
{
await Task.Run(() =>
{
Thread.Sleep(500);
action();
});
fl.Close();
}
我们怎么调用呢?如下:
this.LoadData(() =>
{
// 加载数据
});
当然了这样的封装有点鸡肋,不能跨线程,那么我们来封装有返回值的如下:
protected async Task<IEnumerable<T>> LoadData<T>(Func<IEnumerable<T>> func)
{
if(func==null)
return Enumerable.Empty<T>();
IEnumerable<T> list;
using (FmLoading fl = new FmLoading())
{
var tempData= ((Func<FmLoading,Task<IEnumerable<T>>>)(async (FmLoading f) =>
{
var result = await Task.Run(() =>
{
Thread.Sleep(500);
return func();
});
f.Close();
return result;
})).Invoke(fl);
fl.ShowDialog();
list= await tempData;
}
return list;
}
如何调用?如下:
封装了一个有参有返回值的异步加载,其它自行扩展
protected IEnumerable<T> LoadData<T>(Func<object[],IEnumerable<T>> func, params object[] objects)
{
if (func == null)
return Enumerable.Empty<T>();
IEnumerable<T> list;
using (FmLoading fl = new FmLoading())
{
var tempData = LoadDataAsync(func, fl, objects);
fl.ShowDialog();
list = tempData.Result;
}
return list;
}
private async Task<IEnumerable<T>> LoadDataAsync<T>(Func<object[],IEnumerable<T>> func, FmLoading fl, params object[] objects)
{
var result = await Task.Run(() =>
{
Thread.Sleep(500);
return func(objects);
});
fl.Close();
return result;
}