如何从异步任务返回结果

本文关键字:返回 结果 任务 异步 | 更新日期: 2023-09-27 18:18:25

我想从异步任务返回一个字符串结果。

System.Threading.Tasks.Task.Run(async () => await audatex.UploadInvoice(assessment, fileName));
public async Task UploadInvoice(string assessment, string fileName)
{
    //Do stuff
    return string;
}

异步编程让我困惑,有人能解释一下吗?

如何从异步任务返回结果

异步编程可能需要一段时间才能让你理解,所以我将把对我有用的东西贴出来,以防它对其他人有所帮助。

如果你想从异步代码中分离业务逻辑,你可以保持你的UploadInvoice方法async-free:

private string UploadInvoice(string assessment, string filename)
{
    // Do stuff    
    Thread.Sleep(5000);
    return "55";
}

然后你可以创建一个异步包装器:

private async Task<string> UploadInvoiceAsync(string assessment, string filename)
{
    return await Task.Run(() => UploadInvoice(assessment, filename));
}

让您选择调用哪个:

public async Task CallFromAsync()
{
    string blockingInvoiceId = UploadInvoice("assessment1", "filename");
    
    string asyncInvoiceId = await UploadInvoiceAsync("assessment1", "filename");
}

有时候你可能需要从一个非异步方法中调用一个异步方法。

// Call the async method from a non-async method
public void CallFromNonAsync()
{
    string blockingInvoiceId = UploadInvoice("assessment1", "filename");
                
    Task<string> task = UploadInvoiceAsync("assessment1", "filename");
        string invoiceIdAsync = task.GetAwaiter().GetResult();
}

----编辑:添加更多的例子,因为人们发现这很有用----

有时候你想等待一个任务,或者在完成时用一个方法继续一个任务。下面是一个可以在控制台应用程序中运行的工作示例。

class Program
{
    static void Main(string[] args)
    {
        var program = new Program();
        program.Run();
        Console.ReadKey();
    }
    
    async void Run()
    {
        // Example 1
        Console.WriteLine("#1: Upload invoice synchronously");
        var receipt = UploadInvoice("1");
        Console.WriteLine("Upload #1 Completed!");
        Console.WriteLine();
    
        // Example 2
        Console.WriteLine("#2: Upload invoice asynchronously, do stuff while you wait");
        var upload = UploadInvoiceAsync("2");
        while (!upload.IsCompleted)
        {
            // Do stuff while you wait
            Console.WriteLine("...waiting");
            Thread.Sleep(900);
        }
        Console.WriteLine("Upload #2 Completed!");
        Console.WriteLine();
    
        // Example 3
        Console.WriteLine("#3: Wait on async upload");
        await UploadInvoiceAsync("3");
        Console.WriteLine("Upload #3 Completed!");
        Console.WriteLine();
    
        // Example 4
        var upload4 = UploadInvoiceAsync("4").ContinueWith<string>(AfterUploadInvoice);
    }
    
    string AfterUploadInvoice(Task<string> input)
    {
            Console.WriteLine(string.Format("Invoice receipt {0} handled.", input.Result));
        return input.Result;
    }
    
    string UploadInvoice(string id)
    {
        Console.WriteLine(string.Format("Uploading invoice {0}...", id));
        Thread.Sleep(2000);
        Console.WriteLine(string.Format("Invoice {0} Uploaded!", id));
        return string.Format("<{0}:RECEIPT>", id); ;
    }
    Task<string> UploadInvoiceAsync(string id)
    {
        return Task.Run(() => UploadInvoice(id));
    }
}

你的方法应该返回Task<string>,而不是Task:

public async Task<string> UploadInvoice(string assessment, string fileName)
{
    //Do stuff
    return "some string";
}
public async Task<string> UploadInvoice(string assessment, string fileName)
{
    string result = GetResultString();//Do stuff    
    return Task.FromResult(result);
}

这样做:

public async Task<string> UploadInvoice(string assessment, string fileName)

然后await结果:

string result = await UploadInvoice("", "");

更多的例子可以在这里看到:

异步返回类型