1.背景:在导出和导入配置文件的时候,采用了新弹出窗体显示导入和导出的进度以及成功失败情况。
2.问题:导入导出的进度条、完成事件的订阅函数处理多次(实际次数跟历史打开该弹窗的次数相同)。
3.原因:如果多次挂载同一事件处理函数,函数将会执行多次。由于在窗体第一次加载时的ProcessForm_Shown函数里为传输进来的同一个ru4对象的事件绑定处理函数,每次show打开窗口,都会订阅一次处理函数,但是没有在btnOK_Click关闭窗体时取消订阅,导致一个事件绑定了多次同一个处理函数(即使是不同对象的)。
4.解决办法:在关闭窗体时取消事件的订阅函数。
namespace ETG1OPHFSoft.GUI
{
/// <summary>
/// 升级或者导出setting
/// </summary>
public enum LoadSettingStyle
{
DownLoad,//升级
Export,//导出
}
public partial class ProcessForm : Form
{
string title = "";
RU4 ru4 = null;
LoadSettingStyle settingStyle;
public string filePath;
public ProcessForm(string title, RU4 ru4, LoadSettingStyle loadSettingStyle)
{
InitializeComponent();
this.btnOK.Visible = false;
this.title = title;
this.label_title.Text = title + "进度";
this.ru4 = ru4;
settingStyle = loadSettingStyle;
}
/// <summary>
/// 第一次加载时发生
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ProcessForm_Shown(object sender, EventArgs e)
{
if (settingStyle == LoadSettingStyle.DownLoad)
{
ru4.communicatThread.RefreshUpdateSettingProBarEvent += processMethod;
ru4.communicatThread.RefreshUpdateSettingEndEvent += endMethod;
ru4.upDataSetting(filePath);
}
else if (settingStyle == LoadSettingStyle.Export)
{
ru4.communicatThread.RefreshExportSettingProBarEvent += processMethod;
ru4.communicatThread.RefreshExportSettingEndEvent += endExportMethod;
ru4.exportSettingFile();
}
this.label_end.Text = title + "正在进行中...";
}
private void btnOK_Click(object sender, EventArgs e)
{
if (settingStyle == LoadSettingStyle.DownLoad)
{
//很重要,一定要在这里取消订阅,close和Dispose窗体都不能自动取消订阅,会导致处理函数执行多次
ru4.communicatThread.RefreshUpdateSettingProBarEvent -= processMethod;
ru4.communicatThread.RefreshUpdateSettingEndEvent -= endMethod;
}
else if (settingStyle == LoadSettingStyle.Export)
{
ru4.communicatThread.RefreshExportSettingProBarEvent -= processMethod;
ru4.communicatThread.RefreshExportSettingEndEvent -= endExportMethod;
}
this.Close();
//this.Dispose();
}
private void endMethod(object obj)
{
bool ret = (bool)obj;
if (ret)
{
this.label_end.Text = title + "已完成";
}
else
{
this.label_end.Text = title + "失败";
}
this.btnOK.Visible = true;
}
private void endExportMethod(object obj)
{
SettingInfoClass settingInfo = (SettingInfoClass)obj;
if (settingInfo!=null)
{
LoadSettingFile loadSetting = new LoadSettingFile();
bool retExport = loadSetting.exportSettingFile(settingInfo);
if (retExport)
{
processMethod(100);//刷新进度条
this.label_end.Text = title + "已完成";
}
else
{
this.label_end.Text = title + "成功,但没保存";
}
}
else
{
this.label_end.Text = title + "失败";
}
this.btnOK.Visible = true;
}
/// <summary>
/// 更新进度条
/// </summary>
/// <param name="obj"></param>
private void processMethod(object obj)
{
int value = (int)obj;
this.proBar1.Value = value;
}
}
}