BusyIndicator не отображается из асинхронного метода

Я пытаюсь обновить методы, которые ранее были основаны на BackgroundWorker, чтобы использовать асинхронные вызовы из библиотеки Microsoft.Bcl.Async. Проблема, с которой я столкнулся, заключается в том, что индикатор занятости больше не работает с новой асинхронной функциональностью (к которой я новичок). Индикатор занятости не отображается, графический интерфейс пользователя зависает во время выполнения операции, а затем размораживается после ее завершения. Я не уверен, что я делаю не так...

Код XAML:

<Border BorderBrush="Black" BorderThickness="1" CornerRadius="5,5,15,15" Background="#FFA8A9AC" Grid.Column="1" Grid.Row="1">
    <Grid x:Name="UIGrid">
        <toolkit:BusyIndicator x:Name="BusyIndicator" IsBusy="{Binding Instance.IsBusy}" BusyContent="{Binding Instance.BusyMessage, TargetNullValue='Please wait...'}" >
            <Grid x:Name="ScreenGrid" />
        </toolkit:BusyIndicator>
    </Grid>
</Border>

Код

// Button click handler.
private async void NewReportClick(object sender, RoutedEventArgs e)
{
    SystemLog.Trace(this);

    await this.CreateReport();
}

// Async implementation.
private async Task CreateReport()
{
    SystemLog.Trace(this);

    await this.CloseReport();

    BusinessLogic.Instance.BusyMessage = "CREATING new report...";
    BusinessLogic.Instance.IsBusy = true;

    await BusinessLogic.Instance.ReportManager.CreateReport();

    BusinessLogic.Instance.IsBusy = false;
    BusinessLogic.Instance.BusyMessage = null;
}

Изменить: Чтобы ответить на @Jon Skeet, вот важные части CreateReport:

    public async Task CreateReport()
    {
        SystemLog.Trace(this);

        var internalReportId = GenerateReportId();

        var rpt = await ReportFactory.Create();

        rpt.InternalReportId = internalReportId;
        rpt.EnableNotifications = true;

        ReportRepository = new ReportRepository();

        await SaveReport(rpt);

        // Set the active report.
        BusinessLogic.Instance.ActiveReport = rpt;

        await AssignReportNumber(MediViewData.Instance.ActiveReport);
    }

    public async static Task<Report> Create()
    {
        var rpt = new Report();

        /** Set several fields to default values. */

        return rpt;
    }

1 ответ

Решение

Недостаточно информации, чтобы дать вам код для ответа, но в целом:

Во-первых, осознайте, что async не запускает ваш код в фоновом потоке. Все, что он делает, это создает маленький конечный автомат, который позволяет await операции. Точно так же, await не запускает ваш код в фоновом потоке.

Если у вас есть ресурсоемкие операции, вы должны перенести их в фоновый поток, используя await Task.Run(..), Любая привязка данных считается операцией пользовательского интерфейса и не должна выполняться внутри вызова Task.Run,

Другие вопросы по тегам