Aelphaeis
Aelphaeis

Reputation: 2613

Async-await Keyword Inquiries

There are some things about the Async-await that just mystify me and I was wondering if anyone could explain something to me:

Just to note, my inquiries come after reading this: http://blogs.msdn.com/b/ericlippert/archive/2010/10/29/asynchronous-programming-in-c-5-0-part-two-whence-await.aspx

So Eric Lippert says

The “async” modifier on the method does not mean “this method is automatically scheduled to run on a worker thread asynchronously”

Why is it that we need to place Async on methods we want to run asynchronously? i.e.

private async Task<int> GetMeInt()
{
    return 0;
}
private async void stuff()
{
    var num = GetMeInt();
    DoStuff();
    int end = await num;
    for (int i = 0; i < end; i++)
        Console.WriteLine("blahblahblah");
}

The thing is that we don't want GetMeInt to actually do anything asynchronous internally. We just want it to run Synchronously, but we want it to run asynchronously as a whole when called by another method. It seems more sensible to me to put the async only on the Stuff() method and allow the GetMeInt() to run on another thread and return later.

Essentially I believe it would be something like such :

private int GetMeInt()
{
    return 0;
}

private async void stuff()
{
    int? num = null;
    Thread t = new Thread(() => num = GetMeInt());
    t.Start();
    DoStuff();
    t.Join();
    for (int i = 0; i < (num??0); i++)
        Console.WriteLine("blahblahblah");
}

After all, isn't the state machine only created on the Stuff() method? What makes it more confusing is the fact that the compiler gives a warning if I do put async in GetMeInt, its not really nice to be forced to wrap whatever is returned by GetMeInt() in the task object and this type of thing prevents us from using methods someone else wrote asynchronously.

Why didn't they design it in such a way so you could do something like this (This is the territory of untested theoretical code!). I'd imagine that there are reasons that have to do with the framework but I'd think that this sort of thing would be more intuitive. Am I missing something obvious about this async business? Am I suppose to just ignore the warning and go ahead, my OCD just won't let this go.

private async void stuff()
{
    var s = Example.Run<int>(Delegate.CreateDelegate(typeof(Delegate), this, "GetMeInt"));
    DoStuff();
    for (int i = 0; i < s.Result; i++)
        Console.WriteLine("blahblahblah");
}

public class Example 
{
    Thread t;
    Object r;
    private Example(){}
    public static Example<T> Run<T>(Delegate pFunc) 
    {
        Example<T> output = new Example<T>();
        output.t = new Thread(() => output.r = (T)pFunc.DynamicInvoke());
        output.t.Start();
        return output;
    }

    public sealed class Example<T> : Example
    {

        public T Result
        {
            get
            {
                t.Join();
                return (T)r;
            }
            private set;
        }
    }
}

I really don't understand, any explanation about this stuff would be appreciated.

Upvotes: 1

Views: 207

Answers (2)

SLaks
SLaks

Reputation: 887777

All the async modifier means is that that this method is able to await things.

As the compiler is warning you, it is completely useless unless you actually have something to await.

You're actually asking how to do work on a background thread, then asynchronously wait for it to finish.
You can use Task.Run() to run code in the background, then await the resulting task.

Upvotes: 5

Mark Sowul
Mark Sowul

Reputation: 10610

The key thing to understand about async is that, strictly speaking, the method returns before its work has completed. That's essentially the only thing the keyword denotes. Your example that returns 0 right away does not do this "offloading" and so the compiler is warning you that there's no point in it being async.

That's why async methods should return a Task<T> (so you can determine when the method's work has actually completed and take action on the now-available result), and that's why anything that uses await has to itself be async (because now that outer method will also return before it is "done").

Upvotes: 0

Related Questions