-1

I am learning the basics of async and await, and sometimes it's not clear whether I should build a method as async or not.

To make the question clear, I wrote two ways below to do the same thing. In both samples below, MyMethod() is called by button1's click event and does (presumably) the same thing:

First way:

public partial class Form1 : Form
{

    public Form1()
    {
        InitializeComponent();
    }
    
    private int MyMethod()
    {
        int x = 0;
    
        do
        {
            Thread.Sleep(100);
            x++;
    
        } while (x < 10);
    
        return x;
    }
    
    private async void button1_Click(object sender, EventArgs e)
    {
        Task<int> task = new Task<int>(MyMethod);
        task.Start();
    
        int MyNumber = await task;
        label1.Text = MyNumber.ToString();
    
    }
}

Second way:

public partial class Form1 : Form
{

    public Form1()
    {
        InitializeComponent();
    }

    private async Task<int> MyMethodAsync()
    {
        int x = 0;

        do
        {
            await Task.Delay(100);
            x++;

        } while (x < 10);

        return x;
    }

    private async void button1_Click(object sender, EventArgs e)
    {
        int MyNumber = await MyMethodAsync();

        label1.Text = MyNumber.ToString();
    }
}    

My confusion is, how do I choose between these two methods? Is there is a recommended way?

As a beginner, my tendency is to convert MyMethod() to a Task only if we need asynchronous tasks inside MyMethod(). But I cannot make a conclusion whether it is fine to implement MyMethod() as a Task in others cases, too.

If the first way works for us, is second way (converting MyMethod to a Task) redundant or could it even have bad consequences?

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
user1999
  • 199
  • 8
  • Does this answer your question? [How and when to use ‘async’ and ‘await’](https://stackoverflow.com/questions/14455293/how-and-when-to-use-async-and-await) – gunr2171 Apr 01 '21 at 14:18
  • No because in both cases I use ‘async’ and ‘await’ in the event. My question is about implementing the called method. – user1999 Apr 01 '21 at 14:20
  • You don't want to use a Task constructor: https://stackoverflow.com/a/34145573/1043380 – gunr2171 Apr 01 '21 at 14:21
  • If you must delay, awaiting `Task.Delay` is better than `Thread.Sleep`. The former frees up the thread to do other things. The latter forces it to do nothing. – Scott Hannen Apr 01 '21 at 14:30
  • So the question is basically whether `await Task.Delay(100)` is preferable to `Thread.Sleep(100)`? In that case here is a relevant question: [When to use Task.Delay, when to use Thread.Sleep?](https://stackoverflow.com/questions/20082221/when-to-use-task-delay-when-to-use-thread-sleep) – Theodor Zoulias Apr 01 '21 at 14:32
  • @TheodorZoulias Not really those are just examples. My question is, if we convert a method to a Task regardless of needing async operations inside MyMethod, does it have any negative consequences. In other words, is there any reason why we would chose First way besides void methods. – user1999 Apr 01 '21 at 14:35
  • So another example that you could have included in your question is whether the [`File.ReadAllTextAsync`](https://learn.microsoft.com/en-us/dotnet/api/system.io.file.readalltextasync) is preferable to the `File.ReadAllText` enclosed in a `Task`? – Theodor Zoulias Apr 01 '21 at 14:42
  • Actually the `File.ReadAllText` [is better than](https://stackoverflow.com/questions/63217657/why-file-readalllinesasync-blocks-the-ui-thread) the `File.ReadAllTextAsync`. Honestly I am still struggling to understand the question. In what way is this question different/more general than a comparison between `Task.Delay` and `Thread.Sleep`? Maybe you could help me understand by providing a different example. – Theodor Zoulias Apr 01 '21 at 15:02
  • @TheodorZoulias I will try but answers are very related what I was asking. – user1999 Apr 01 '21 at 15:04
  • @TheodorZoulias If using File.ReadAllText is better than File.ReadAllTextAsync that is strange to me(as a novice) as well. Because I thought for IO bound methods we always go for async. Maybe you can give me feedback on this example. "In general, you would prefer background threads for CPU-intensive work and asynchronous methods for IO-related work" says one answer. – user1999 Apr 01 '21 at 15:06
  • @TheodorZoulias Thanks I will edit that. – user1999 Apr 01 '21 at 15:27

2 Answers2

0

It depends on what you are doing.

If you are mostly doing IO-related work, opening files, waiting for network etc, then the second example would be most appropriate. This will run any processing on the main thread, so you avoid the overhead of a thread that will mostly be blocked.

If you are doing processing-intensive work the first example would be more appropriate. In this case you would not have anything to await, but you might still want to run it on a background thread to avoid blocking the UI.

JonasH
  • 28,608
  • 2
  • 10
  • 23
0

The difference is basically that your first example executes MyMethod() synchronously (and blocks) on a background thread whereas your second example executes an asynchronous method directly on the dispatcher thread without blocking it.

Which one is better comes down to what the method actually does. In general, you would prefer background threads for CPU-intensive work and asynchronous methods for IO-related work such as when you work with files or send or receive bytes over a network.

On a side note, also note that you should use Task.Run to start a new task rather than using the Task constructor:

Task.Run(MyMethod);
mm8
  • 163,881
  • 10
  • 57
  • 88