Hello,

I'm having a hard time when thinking about methods that belong to objects. Most documentation tells us that objects contain the data and actions for the data. When running as program though, the methods seem like they are actions that belong to the program (get put on the stack for the program and not some special stack belonging to the object). Anyway, this isn't really a question I guess- I don't know how to ask what I am confused about. When I am creating classes and have multiple threads running the idea of methods belonging to the object gets confusing.

I do have a real question. When you have a method being executed ayncronously, does your running program halt, execute that method, then resume with what it was doing? If not, what is going on. Specifically would be, events and Windows Message Pump timer events. Also, other than having multiple threads or using the message pump, how could thinks happen asyncronously?

Thanks

Also, I was reading MSDN documentation about async programming and it says this "The async and await keywords don't cause additional threads to be created. Async methods don't require multithreading because an async method doesn't run on its own thread. The method runs on the current synchronization context and uses time on the thread only when the method is active. You can use Task.Run to move CPU-bound work to a background thread, but a background thread doesn't help with a process that's just waiting for results to become available."

I don't understand when it says "a background thread doesn't help with a process that's just waiting for results to become available". How do results ever become available if there is only one thread running? Does the same thread stop what it is doing, and switch over to another execution path for getting results, and this switch back to its original executation path? If so, that would seem like a thread that has threads.

Thanks again.

Personally I would only use async/await if you're running on the UI context as I believe that's the entire reason it was designed (to prevent blocking the UI thread)

You can have the await chain run serially on it's own context by setting .ConfigureAwait(false) but each method in the chain will run on the same, single ThreadPool thread and therefor run synchronously.

With async/await all you're really doing is promising that a result will come, eventually, when you actually need it, if it isn't finished yet, it will block.

Edited 3 Years Ago by Ketsuekiame

Personally I would only use async/await if you're running on the UI context as I believe that's the entire reason it was designed (to prevent blocking the UI thread)

So in your opinion it's just a more convenient form of BackgroundWorker?

Essentially. I can't say I've used it extensively, nor found the need to. From what I've read about it, it's more of a marketting exercise than being of any particular use.

Thought I'd write some code to try and explain a little better.

Let's say you want to handle some UI updates when you click a button. The data you're retrieving happens by calling a webservice. If you were to call this synchronously, the UI would block :( With the async and await keywords, however, you can alleviate this problem (as shown below)

private async void FetchName_Click(object sender, RoutedEventArgs e)
{
    Task<string> getName = GetNameAsync();

    // This is executed first, updating the UI label.
    // Technically speaking, you can do whatever you want while the 
    // task is active, so long as you don't want the result
    lblStatus.Text = @"Fetching name from service...";

    // At this point, the method blocks and execution reverts back to the calling method.
    // In this case the UI message pump
    string name = await getName;

    lblName.Text = name;

    lblStatus.Text = @"Name updated";
}

private async Task<string> GetNameAsync()
{
    // Create the task to fetch the string
    Task<string> getName = MyService.Instance.GetNameAsync(_userId);

    // Even though we're running from async, we're still on the UI thread at the moment...
    lblStatus.Text = @"Connecting to service...";

    // Control reverts back up the method chain, so back to FetchName_Click, who then goes back to the MessagePump. This stops the UI from locking up.
    // Inside this method, there will probably be some kind of threaded operation as you no longer need to be on the UI context, otherwise, this method will also run synchronously.
    string name = await getName;

    // Back on the UI thread...
    lblStatus.Text = @"Data from service found.";

    return name;
}

So as you can see, at some point, if you want this to be multithreaded, you have to do it yourself otherwise you will end up blocking.

A simpler example; create a Winforms project with two buttons on. Button1 and Button2.

Paste the following code into your Form code file:

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();
    }

    private async void Button_Click(object sender, EventArgs e)
    {
        Task<bool> updateButton = UpdateButtonAsync();
        button1.Enabled = false;

        button1.Enabled = await updateButton;
    }

    private async Task<bool> UpdateButtonAsync()
    {
        await Task.Run(() =>
        {
            Thread.Sleep(10000);    
        });
        return true;
    }
}

Link Button1 to the Button_Click method. Now run the program and click Button1. You will notice that the button is disabled for 10 seconds and then re-enabled itself. However, importantly, button2 can still be pressed.

Now, comment out lines 1, 2 and 4 of the UpdateButtonAsync method. Press Button1 again and it will lock the thread. The UI becomes unresponsive. You will also get compiler/intellisense warnings to this effect.

Edited 3 Years Ago by Ketsuekiame: Added another example

So in your opinion it's just a more convenient form of BackgroundWorker?

Yes. It creates and handles the threading and callback for you. At least, that was how it was shown and explained by MS. If you look at the IL, you should see an old fashioned thread solution.

The reason for it was to simplify building Metro apps, as the UI needs to be responsive at all times, and using the same thread solution over and over is kind of bulky.

Edited 3 Years Ago by pritaeas

This article has been dead for over six months. Start a new discussion instead.