我有一种方法来显示带有参数Func<T>
的加载表单,在这种方法中,我使用func.Invoke();。 this.Close();
但在此强制this.Close();不等待func.Invoke完成。
请帮助我。
private void ShowLoading<T>(Func<T> func)
{
func.Invoke();
this.Close();
}
private void Button1_Click_1(object sender, EventArgs e)
{
ShowLoading(() =>
{
Server server = new Server(new ServerConnection(".\\sqlexpress", "sa", "underadmin"));
Backup backup = new Backup() { Action = BackupActionType.Database, Database = "TestMedia" };
backup.Devices.AddDevice(@"D:\BACKUP\TestMedia.bak", DeviceType.File);
backup.Initialize = true;
backup.PercentComplete += Backup_PercentComplete;
backup.SqlBackupAsync(server);
return 0;
});
}
答案 0 :(得分:1)
使您的点击处理程序异步,并在委托中设置TaskCompletionSource。
为此,您必须将委托定义为Func<Task<int>>
,因为所有等待的方法都必须返回某种Task<>
。
private async Task ShowLoading(Func<Task<int>> func)
{
await func.Invoke();
this.Close();
}
private async void Button1_Click_1(object sender, EventArgs e)
{
await ShowLoading( () =>
{
var source = new TaskCompletionSource<int>();
Server server = new Server(new ServerConnection(".\\sqlexpress", "sa", "underadmin"));
Backup backup = new Backup() { Action = BackupActionType.Database, Database = "TestMedia" };
backup.Devices.AddDevice(@"D:\BACKUP\TestMedia.bak", DeviceType.File);
backup.Initialize = true;
backup.PercentComplete += Backup_PercentComplete;
backup.Complete += (s,e) => { source.SetResult(0); };
backup.SqlBackupAsync(server);
return source.Task;
});
}
但是更简单的方法是使用close动作处理Complete
事件。
private void Button1_Click_1(object sender, EventArgs e)
{
Server server = new Server(new ServerConnection(".\\sqlexpress", "sa", "underadmin"));
Backup backup = new Backup() { Action = BackupActionType.Database, Database = "TestMedia" };
backup.Devices.AddDevice(@"D:\BACKUP\TestMedia.bak", DeviceType.File);
backup.Initialize = true;
backup.PercentComplete += Backup_PercentComplete;
backup.Complete += (o,e) => { this.Close(); };
backup.SqlBackupAsync(server);
}
答案 1 :(得分:0)
要考虑的一个选项是添加一个新方法,当备份为completed时将调用该方法-调用this.Close
是该方法的责任。
您执行此操作的方式与使用PercentComplete
的操作类似:
backup.PercentComplete += Backup_PercentComplete;
因此它将是:
backup.Complete += Backup_Complete; // or whatever you want the method to be called:
Backup_Complete
的代码行为this.Close;
,而不是ShowLoading
。
答案 2 :(得分:0)
谢谢大家,现在我有一个解决方案。只需将backup.sqlBackupAsync更改为backup.sqlBackup,然后在ShowLoading方法中,在DoWork中创建一个新的BackgroudWorker,然后添加fucn.Invoke();。然后在DoWorkCompleted中,我称之为this.Close();工作正常:)
private void Button1_Click_1(object sender, EventArgs e)
{
ShowLoading(() =>
{
Server server = new Server(new ServerConnection(".\\sqlexpress", "sa", "underadmin"));
Backup backup = new Backup() { Action = BackupActionType.Database, Database = "TestMedia" };
backup.Devices.AddDevice(@"D:\BACKUP\TestMedia.bak", DeviceType.File);
backup.Initialize = true;
backup.PercentComplete += (s, ev) => lblPercent.Text = ev.Percent.ToString();
backup.SqlBackup(server);
return 0;
});
}
private void ShowLoading<T>(Func<T> func)
{
var bgk = new BackgroundWorker();
bgk.DoWork += (s, e) => func.Invoke();
bgk.RunWorkerCompleted += (s, e) => this.Close();
bgk.RunWorkerAsync();
}