如何等待 Func<T>().Invoke
How to wait Func<T>().Invoke
我有一个方法来显示带有参数 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;
});
}
使您的点击处理程序异步并在委托中设置 TaskCompletionSource。
为此,您必须将委托定义为 Func<Task<int>>
,因为所有可等待的方法都必须 return 某种 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;
});
}
但更简单的方法是使用关闭操作处理 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);
}
要考虑的一个选项是添加一个新方法,该方法在备份 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
.
谢谢大家,现在我有办法了。只需将 backup.sqlBackupAsync 更改为 backup.sqlBackup 然后我在方法 ShowLoading 中创建一个新的 BackgroudWorker 在 DoWork 我添加 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();
}
我有一个方法来显示带有参数 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;
});
}
使您的点击处理程序异步并在委托中设置 TaskCompletionSource。
为此,您必须将委托定义为 Func<Task<int>>
,因为所有可等待的方法都必须 return 某种 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;
});
}
但更简单的方法是使用关闭操作处理 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);
}
要考虑的一个选项是添加一个新方法,该方法在备份 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
.
谢谢大家,现在我有办法了。只需将 backup.sqlBackupAsync 更改为 backup.sqlBackup 然后我在方法 ShowLoading 中创建一个新的 BackgroudWorker 在 DoWork 我添加 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();
}