有没有办法让我等待当前不是异步的方法?

Is there a way that I can await a method that's currently not async?

按下按钮后 运行 我有这段代码:

    partial void DownloadPressed(NSObject sender)
    {
        Console.WriteLine("Pressed");

        BeginInvokeOnMainThread(() => {
            Label1.StringValue = "Fetching Data";
            Label2.StringValue = "Fetching Data";
            Label3.StringValue = "Fetching Data";
        );
        DownloadFromAzure();
        Label1.StringValue = "Phrases: " + psNet.Count;
        Label2.StringValue = "CategorySource: " + csNet.Count;
        Label3.StringValue = "CategoryGroupSource: " + cgsDb;
    } 

我尝试了很多不同的方法,但我无法让它显示“正在获取数据”消息。我认为这是因为所有 运行 都在同一个线程中,无需等待。

任何人都可以就如何 运行 等待方法提出建议。

    private static void DownloadFromAzure()
    {
        // Some database and HTTP calls here

    }

呃..不是吗?

await 要求参数是可等待的。请参阅 https://blogs.msdn.microsoft.com/pfxteam/2011/01/13/await-anything/ 如何为不 return 任务<>...

但我不确定是否真的值得付出努力。它 仍然需要 您能够跟踪待处理作业的 start/progress/stop/error 条件,并且考虑到您只有一个线性函数调用,您可能没有任何此类信息手.

最好 refactor/redesign DownloadFromAzure 实际上 return 一个您可以轻松等待的任务。

编辑:

在可怕的情况下,你总是可以用 Task.Run

包装它
partial async Task DownloadPressed(NSObject sender)
{
    Console.WriteLine("Pressed");

    BeginInvokeOnMainThread(() => {
        Label1.StringValue = "Fetching Data";
        Label2.StringValue = "Fetching Data";
        Label3.StringValue = "Fetching Data";
    );

    await Task.Run( () => DownloadFromAzure() );   // <-----HERE

    Label1.StringValue = "Phrases: " + psNet.Count;
    Label2.StringValue = "CategorySource: " + csNet.Count;
    Label3.StringValue = "CategoryGroupSource: " + cgsDb;
} 

如果我没理解错的话,您想将对 DownloadFromAzure() 的同步调用转换为等待调用。

有多种方法可以做到这一点,包括将 DownloadFromAzure() 修改为异步方法。

但如果这不是最好的方法(可能是这种情况),您可以简单地将其包装成 Task:

await Task.Run(() => DownloadFromAzure());

更新,由于评论:

partial void DownloadPressed(NSObject sender)
{
    Console.WriteLine("Pressed");

    DoDownloadAsync();
}

private async void DoDownloadAsync()
{
    BeginInvokeOnMainThread(() => {
        Label1.StringValue = "Fetching Data";
        Label2.StringValue = "Fetching Data";
        Label3.StringValue = "Fetching Data";
    );

    await Task.Run(() => DownloadFromAzure());

    Label1.StringValue = "Phrases: " + psNet.Count;
    Label2.StringValue = "CategorySource: " + csNet.Count;
    Label3.StringValue = "CategoryGroupSource: " + cgsDb;
}

请注意,这是一种 "fire and forget" 方法,如果 DoDownloadAsync() 自行负责进行适当的错误处理(可能包含在 DownloadFromAzure()此处)和调用者(DownloadPressed 此处)不关心跟踪 Task 的进度! 在任何其他情况下,DoDownloadAsync() 应该 return 它正在等待的 Task,以便调用者能够跟踪。

见e。 G。在这里进行更深入的讨论:async/await - when to return a Task vs void?

答案是

official documentation 中等待关键字:

The await operator is applied to a task in an asynchronous method to insert a suspension point in the execution of the method until the awaited task completes. The task represents ongoing work.

await can only be used in an asynchronous method modified by the async keyword. Such a method, defined by using the async modifier and usually containing one or more await expressions, is referred to as an async method.

那么,您的选择是:

  1. DownloadFromAzure()设为asnyc
  2. 添加以下代码:

    await Task.Run(() => DownloadFromAzure())