How to Await F# Async Code Method from C# ( WPF )

I write most of my backend code in F# – but my WPF project is in C# and I am wiring up progress reporting between the process and UI.

My F# Code

type DownloadProgressModel = {
        mutable PercentageComplete: int
        totalOrders: int
        mutable orderPosition: int
    }

let doMockDownload(progress: IProgress<DownloadProgressModel>) = async {
        let downloadprogress: DownloadProgressModel = {
            PercentageComplete = 0
            totalOrders = 20
            orderPosition = 0
        }
        for i in [0..20] do
            do! Async.Sleep(2000)
            downloadprogress.orderPosition <- i
            downloadprogress.PercentageComplete <- (i*100) / 20
            progress.Report(downloadprogress)
        return "Finished"
    }

My C# calling code from a WPF View

private async void SimpleButton_Click(object sender, RoutedEventArgs e)
        {
            Progress<DownloadProgressModel> progress = new Progress<DownloadProgressModel>();
            progress.ProgressChanged += Progress_ProgressChanged;
            var a = await MockDownload.doMockDownload(progress);
        }

        private void Progress_ProgressChanged(object sender, DownloadProgressModel e)
        {
            ordersProgress.Value = e.PercentageComplete;
        }

I get the following Error: ( the offending line var a = await MockDownload.doMockDownload(progress); )

‘FSharpAsync’ does not contain a definition for ‘GetAwaiter’
and no accessible extension method ‘GetAwaiter’ accepting a first
argument of type ‘FSharpAsync’ could be found (are you missing
a using directive or an assembly reference?)

This is losely based on C# Advanced Async – Getting progress reports, cancelling tasks, and more by "IamTimCorey" on youtube – but that is all C#.

>Solution :

The F# async computation expression is not directly compatible with C# async keyword. For code you control, that is meant to be consumed from C# you are probably best off to switch for the task computation expression instead

Alternately, you can use Async.StartAsTask to convert an Async<'T> to Task<'T>.

Leave a Reply