Mahapps ShowProgressBarAsync仅在我的加载任务完成后显示

时间:2015-08-10 07:59:12

标签: c# asynchronous async-await mahapps.metro

我正在尝试使用应用程序的mahaps进度条对话框在任务启动时触发,通常会冻结应用程序几秒钟。

private void Button_Click(object sender, RoutedEventArgs e)
{
    LoadingDialog();

    SaveAndLoadData.SaveUserData(ApplicationData.UserData);
    MainWindowLogic.LogIntoWebsites();
}

private async void LoadingDialog()
{
    var controller = await this.ShowProgressAsync("Logging In...", "");
}

在我的LogIntoWebsites()方法完成之后,实际上不会弹出“加载”对话框。我感觉我并没有理解异步,而且我肯定在这里做错了。

想法?

2 个答案:

答案 0 :(得分:1)

您在“火灾中”调用LoadingDialog并忘记"执行方式。我不确定你想做什么。

如果您希望对话框显示在LogIntoWebsites之前,则需要将方法签名从async void更改为async Task,并使用{{1}异步等待它}}:

await

答案 1 :(得分:0)

我不熟悉Mahaps进度条,但是如果你想使用async-await模式保持你的UI响应,你应该声明你的事件处理程序是异步的。

  

事件处理程序是唯一可以返回void的异步函数,不必返回任务或任务<TResult&gt;

在此异步事件处理程序中,您不必创建新任务。只需调用普通函数,只要您认为函数可能需要一些时间,请将函数声明为异步并等待及时操作。

您的事件处理程序调用三个函数。我不知道哪些需要很长时间才能执行。所以我们假设只有第一个相对较慢。代码如下所示:

private **async** void Button_Click(object sender, ...)
{
    await LoadingDialog();
    SaveAndLoadData.SaveUserData(ApplicationData.UserData);
    MainWindowLogic.LogIntoWebsites();
}

private async void LoadingDialog()
{
    var controller = await this.ShowProgressAsync("Logging In...", "");
}

如果SaveUserData和LogIntoWebsites也相当慢,请考虑为它们创建异步版本。如果他们可以调用异步函数,那么异步版本相当容易。如果不是,你将不得不自己创建一个任务并等待它们。例如:

private async void LogIntoWebSitesAsync()
{
    // do some processing
    // if possible call other async functions
    await OtherFunctionAsync(); // use this if return value is Task
    TResult result = await YetAnotherAsync(); // use if return Task`<TResult`>
    // here you can use result

    // or if you want some parallel processing:
    var taskA = YetAnotherAsync();
    // while taskA is performing, do other things
    // after a while you need the result:
    TResult taskAResult = await taskA;

    // or even start several tasks:
    var taskX = functionXAsync(...);
    var taskY = functionYAsync(...);
    // do some more processing, and after a while you need the results:
    await Task.WhenAll( new Task[] {taskX, taskY});
    var Xresult = taskX.Result;
    var Yresult = taskY.Result;
    ProcessResults(XResult, YResult);
}

如果您的事件处理程序需要调用没有同步版本的长函数,请为它创建一个任务并等待它:

private TResult LongFunction()
{
    // do something slow
    TResult result = ...;
    return result;
}

private async Task`<TResult`> LongFunctionAsync(...)
{
    // do some processing
    // start the task
    var longTask = Task.Run( () => LongFunction(...);
    // while longTask running, do some more processing
    // when the result is needed:
    TResult result = await longTask;

    // or if you don't have anything else to do you can await immediately
    await Task.Run ( () => {...} );
    return result;
}

private async void Button_Click(object sender, ...)
{
    TResult result = await LongFunctionAsync(...);
    ProcessResult(result);
}