0

Let's consider the next procedures hierarhy

    Main.cs:
          // timer callback
          {
             Plot.UpdateData();
          }

    Plot.cs:
            public async void UpdateData()
            {
                await CalculateData();
                // ...
            }

            private async Task CalculateData()
            {
                    await Calculations.Calculate();
                    // UI updating
                    // ...
            }


    Calculations.cs:
            public static async Task<bool> Calculate()
            {
                async Task<bool> CalculateLR()
                {
                    var task1 = Calculate1(); 
                    var task2 = Calculate2();
                    await Task.WhenAll(new[] { task1, task2 });
                    return true;
                }

                var leftTask = CalculateLR();
                var rightTask = CalculateLR();
                await Task.WhenAll(new[] { leftTask, rightTask });

                await Calculate3();

                return true;
            }

Here I have some basic calculations (in Calculate1-Calculate3 procedures) of Calculations.cs file and some interaction with UI. The "entry point" Plot.UpdateData is placed in Device.StartTimer( block of the main form.

It works, but I think this structure creates excess threads. So my question is can this hierarhy be optimized without loss of asynchronous advantages? Or, other words, which procedures should be awaited in case of nested calls. Where is first non-awaited call should lie? Thanks.

Miamy
  • 2,162
  • 3
  • 15
  • 32
  • 2
    What makes you think that it's creating excess threads? Have a look at this... https://stackoverflow.com/questions/27265818/does-the-use-of-async-await-create-a-new-thread – Scott Perham Jan 30 '18 at 11:33
  • Tasks don't directly relate to threads. The scheduler will allocate available to tasks to threads, but you'd be surprised to see how many actually run synchronously on the current thread because they don't have any points to cede control on (such as IO). – Adam Houldsworth Jan 30 '18 at 11:33
  • "I think this structure creates excess threads" that's wrong thinking. – Camilo Terevinto Jan 30 '18 at 11:34
  • ScottPerham, Adam, Camilo, thank you. So if I want to use multi-theading in my calculations, I need to replace await Task.WhenAll(new[] { leftTask, rightTask }); with Parallel.Invoke(() => Calculate1(), () => Calculate2()); , am I right? – Miamy Jan 30 '18 at 12:00

1 Answers1

1

First thing to note: async/await is about tasks, not threads. Under certain circumstances, a task can be thread equivalent, and in most cases it is not (the same thread can serve a lot of tasks sequentially conveyor-style, depending on how they're scheduled for continuation and what is awaiting condition, for example).

And I could strongly recommend to address this for further reading as very comprehensive source: https://blog.stephencleary.com/2013/11/there-is-no-thread.html https://blog.stephencleary.com/2014/05/a-tour-of-task-part-1-constructors.html

Yury Schkatula
  • 5,291
  • 2
  • 18
  • 42
  • I have checked thread id's and see my mistake now. Thank you for the advance! So if I want to use multi-theading in my calculations, I need to replace await Task.WhenAll(new[] { leftTask, rightTask }); with Parallel.Invoke(() => Calculate1(), () => Calculate2()); , am I right? – Miamy Jan 30 '18 at 12:12