做的服务软件,客户要求页面加载要快,但是实际客户的基础数据有部分相当大,几千到几万不等,所以使用了BackgroundWorker来后台加载数据,这个已完成,可以见文章 https://blog.csdn.net/liubing5188/article/details/98213534;
这段时间,客户的主业务保存后,又新增了几个上传同步接口(这几个接口属于非业务主流程,我也不用管它是否成功,只管调用,所以开启异步),想着既然BackgroundWorker好用,就直接参考了上述方法,结果发现虽然异步调用了,但是当对方接口不通或网络异常时,我的主业务完成后,到接口处卡死了,发现这个异步阻塞了主线程,网上找了下发现了一篇文章 https://www.cnblogs.com/huangcong/p/3409333.html ,这篇文章里看到了原因:
Control的Invoke和BeginInvoke的委托方法是在主线程,即UI线程上执行。(也就是说如果你的委托方法用来取花费时间长的数据,然后更新界面什么的,千万别在主线程上调用Control.Invoke和Control.BeginInvoke,因为这些是依然阻塞UI线程的,造成界面的假死)
采用了文章里的
二、用委托(Delegate)的BeginInvoke和EndInvoke方法操作线程
然后测试发现,单独的委托线程,不会阻塞主线程;
这个就很好用了,比如我调用的发药机
private void save()
{
//完成主业务的保存动作
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// 最后委托异步操作
DrugSendMachineHandler drugHandler = new DrugSendMachineHandler(DrugSendMachine);
drugHandler.BeginInvoke(this.register_info, array_invoices, array_invoiceDetails, array_feeitem, null, null);
}
#region 异步调用发药机
/// <summary>
/// 声明发药机异步委托
/// </summary>
/// <param name="urlCode"></param>
/// <param name="r"></param>
public delegate void DrugSendMachineHandler(Mandala.HIS.Models.Registration.Register rInfo, ArrayList invoices, ArrayList invoiceDetails, ArrayList feeDetails);
/// <summary>
/// 委托调用的方法
/// </summary>
/// <param name="rInfo"></param>
/// <param name="invoices"></param>
/// <param name="invoiceDetails"></param>
/// <param name="feeDetails"></param>
public void DrugSendMachine(Mandala.HIS.Models.Registration.Register rInfo, ArrayList invoices, ArrayList invoiceDetails, ArrayList feeDetails)
{
try
{
//封装好的发药机接口
DrugSendMachine.DrugSendToMachine drugSend = new DrugSendMachine.DrugSendToMachine();
int dsresult = drugSend.SendDrugInfo(rInfo, invoices, invoiceDetails, feeDetails);
}
catch { }
}
#endregion