Как ждать Func <T>(). Invoke - PullRequest
       47

Как ждать Func <T>(). Invoke

0 голосов
/ 05 июня 2019

У меня есть метод для отображения формы загрузки с параметром 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;
    });
}

Ответы [ 3 ]

1 голос
/ 05 июня 2019

Сделайте ваш обработчик кликов асинхронным и установите 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;
    });
}

Но гораздо более простой способ сделать это - просто обработать событие Complete с помощью действия close.

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);
}
0 голосов
/ 05 июня 2019

Спасибо всем, парень, теперь у меня есть решение. Просто измените backup.sqlBackupAsync на backup.sqlBackup, а затем я в методе ShowLoading создаю новый BackgroudWorker в DoWork и добавляю fucn.Invoke (); затем в DoWorkCompleted я вызываю this.Close (); отлично работает :) 1001 *

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();
    }
0 голосов
/ 05 июня 2019

Один из возможных вариантов - добавить новый метод, который вызывается, когда резервное копирование завершено - и обязанность этого метода вызывать 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.

...