4

I wanted to experiment with async and await but I had a fiasco. I have the method which need to run two methods asynchronously(it works partly)

public void Run()
{
            Task[] tasks = new Task[2];
            tasks[0] = Task.Factory.StartNew(DisplayInt);
            tasks[1] = Task.Factory.StartNew(DisplayString);

            //block thread until tasks end
            Task.WaitAll(tasks);
}

And two methods which are used

public async void DisplayInt()
    {
        Task<int> task = new Task<int>(
            () => 10);
        task.Start();
        Console.WriteLine(await task);
    }

    public async void DisplayString()
    {
        Task<string> task = new Task<string>(
           () => "ok" );
        task.Start();
        Console.WriteLine(await task);
   }

And usually I got next results:1) 10 ok

or 2)ok 10

but sometimes I got 3)nothing

How to get exactly result from async methods via await without using task.Result or it cannot happen?

3
  • 1
    Is writing to the console from many threads even safe? I can't remember right now. Commented Oct 17, 2015 at 18:08
  • 1
    Yes, links: msdn.microsoft.com/en-us/library/system.console.aspx and stackoverflow.com/questions/1079980/…. Commented Oct 17, 2015 at 18:34
  • You can also do task.GetAwaiter().GetResult(), which is different from task.Result in that it doesn't wrap exceptions with AggregateException. Commented Oct 17, 2015 at 22:46

2 Answers 2

6

I recommend you read some introductory articles like my own async intro, and follow that up with my MSDN article on async best practices. If you just bang out code, you're going to end up with a lot of pain.

In particular, you should not use Task.Factory.StartNew, the Task constructor, nor Task.Start; and you should avoid async void (all links are to my blog where I explain in detail why).

To answer your actual question:

How to get exactly result from async methods via await without using task.Result or it cannot happen?

To get the result from a task, you can either asynchronously wait for the task to complete (via await), or you can synchronously (blocking) wait for the task to complete (via Result). There's no "other way", if that's what you're asking.

Sign up to request clarification or add additional context in comments.

Comments

1

Welcome to SO...

Well, in your case for both tasks it takes more time to initialize them, then to run the method inside. That's why sometimes second task finishes before the first one (if it was initialized in shorter time). If you change your DisplayString method to :

    public static async void DisplayString()
    {
        Task<string> task = new Task<string>(
            () => { Thread.Sleep(10); return "ok"; });
        task.Start();
        Console.WriteLine(await task);
    }

As now DisplayString method now takes around 10 ms to execute It'll will always result in :

10    
ok

P.S. As pointed by Stephen Cleary you can read some basic articles about async / await. I'd also recommend to test it on WinForms projects rather then doing it with Console.

1 Comment

Sleep-based sync is not quite a good practice - I think you should add that it's only for demo purposes. Someone inexperienced might take your example as a pattern to use.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.