如何从异步任务返回结果?

Pom*_*ter 13 c# async-await

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

System.Threading.Tasks.Task.Run(async () => await audatex.UploadInvoice(assessment, fileName));

public async Task UploadInvoice(string assessment, string fileName)
{
    //Do stuff
    return string;
}
Run Code Online (Sandbox Code Playgroud)

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

stu*_*zor 25

异步编程可能需要一段时间才能解决问题,因此我会发布对我有用的内容,以防它帮助其他任何人.

如果要将业务逻辑与异步代码分开,可以使UploadInvoice方法保持无异步:

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

    return "55";
}
Run Code Online (Sandbox Code Playgroud)

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

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

给你选择的电话:

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

    string asyncInvoiceId = await UploadInvoiceAsync("assessment1", "filename");
}
Run Code Online (Sandbox Code Playgroud)

有时您可能需要从非异步方法调用异步方法.

// Call the async method from a non-async method
public void CallFromNonAsync()
{
    string blockingInvoiceId = UploadInvoice("assessment1", "filename");

    Task<string> task = Task.Run(async () => await UploadInvoiceAsync("assessment1", "filename"));
    task.Wait();
    string invoiceIdAsync = task.Result;
}
Run Code Online (Sandbox Code Playgroud)

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

有时您希望等待任务,或者在完成时使用方法继续执行任务.这是一个可以在控制台应用程序中运行的工作示例.

    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));
        }
    }
Run Code Online (Sandbox Code Playgroud)

  • CallFromNonAsync() 可能会死锁,具体取决于这是否是线程池线程。 (3认同)
  • 如果您位于线程池线程上,请不要阻塞等待线程池线程完成。这就是僵局的由来。 (2认同)

w.b*_*w.b 20

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

public async Task<string> UploadInvoice(string assessment, string fileName)
{
    //Do stuff
    return string;
}
Run Code Online (Sandbox Code Playgroud)

  • await 运算符需要在异步和返回类型任务中。如果我添加 Task.Run(async () =&gt; wait UploadInvoice .. 我得到错误.. 不能隐式转换类型 'System.Threading.Tasks.Task&lt;string&gt;' 到 'string' (3认同)

小智 7

public async Task<string> UploadInvoice(string assessment, string fileName)
{
    string result = GetResultString();//Do stuff    
    return Task.FromResult(result);
}
Run Code Online (Sandbox Code Playgroud)

  • 虽然此代码片段可能是解决方案,但[包括解释](//meta.stackexchange.com/questions/114762/explaining-entirely-‌​code-based-answers)确实有助于提高帖子的质量。请记住,您是在为将来的读者回答问题,而那些人可能不知道您建议代码的原因。 (4认同)