質問

I'm trying to upgrade methods, which were previously BackgroundWorker based, to use the async calls from the Microsoft.Bcl.Async library. The trouble I'm having is the busy indicator no longer works with the new async functionality (which I am new to). The busy indicator does not show, the GUI freezes while the operation executes, and then unfreezes when it is complete. I'm not sure what I'm doing wrong...

XAML Code:

<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>

Code

// 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;
}

Edit: To reply to @Jon Skeet, here is the important portions of 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;
    }
役に立ちましたか?

解決

There's not enough information to give you code for an answer, but in general:

First, realize that async does not run your code on a background thread. All it does is create a little state machine that enables await operations. Likewise, await does not run your code on a background thread.

If you have CPU-intensive operations, you should push them off to a background thread using await Task.Run(..). Any kind of data binding is considered a UI operation and should not be done inside a call to Task.Run.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top