web-dev-qa-db-fra.com

Comment retourner un résultat d'une tâche asynchrone?

Je voudrais renvoyer un résultat de chaîne d'une tâche asynchrone.

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

public async Task UploadInvoice(string assessment, string fileName)
{
    //Do stuff
    return string;
}

La programmation asynchrone me trouble, quelqu'un peut-il s’expliquer?

9
Pomster

Votre méthode devrait renvoyer Task<string>, pas Task:

public async Task<string> UploadInvoice(string assessment, string fileName)
{
    //Do stuff
    return string;
}
15
w.b

La programmation async peut prendre un certain temps, donc je vais publier ce qui m'a été utile au cas où cela pourrait aider quelqu'un d'autre.

Si vous souhaitez séparer la logique applicative du code async, vous pouvez conserver votre méthode UploadInvoice sans async:

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

    return "55";
}

Ensuite, vous pouvez créer un wrapper asynchrone:

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

Vous donnant le choix d'appeler:

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

    string asyncInvoiceId = await UploadInvoiceAsync("assessment1", "filename");
}

Parfois, vous devrez peut-être appeler une méthode asynchrone à partir d'une méthode non asynchrone. 

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

---- EDIT: Ajouter plus d'exemples parce que les gens ont trouvé cela utile ----

Parfois, vous souhaitez attendre une tâche ou poursuivre une tâche avec une méthode à la fin. Voici un exemple de travail que vous pouvez exécuter dans une application console.

    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));
        }
    }
21
stuzor
public async Task<string> UploadInvoice(string assessment, string fileName)
{
    string result = GetResultString();//Do stuff    
    return Task.FromResult(result);
}
0
Jayesh Dhananjayan