0

I'm new to parallel programming, threading, tasks, etc. So, I was reading the other day and the book introduced me to Threading. It didn't explain it that well so I was a bit lost in the concept. I have a couple of questions:

  1. Are threads asynchronous by default? Because, when we run multiple threads, it would run and doesn't stop any other threads or tasks, making them asynchronous, I guess.

  2. How does aggregate exception works? I mean like how do we handle it, how did it happened? Please give me an example.

  3. What are synchronization contexts? I've looked up online and seen so many definitions of it. Some try to use smart sounding-words which just cause confusion in my brain.

I've heard that all of these concepts are complicated. Complication drives me to learn even more about it.

Marc2001
  • 281
  • 1
  • 3
  • 12
  • 1
    http://www.albahari.com/threading/ provides a very accessible explanation for all of these things. – Robert Harvey Aug 25 '18 at 03:51
  • These MS Docs guide you to Synchronous and Asynchronous operation. Take a look at that. https://learn.microsoft.com/en-us/dotnet/framework/wcf/synchronous-and-asynchronous-operations – Keyur Ramoliya Aug 25 '18 at 03:56
  • Possible duplicate of [Asynchronous vs synchronous execution, what does it really mean?](https://stackoverflow.com/questions/748175/asynchronous-vs-synchronous-execution-what-does-it-really-mean). For the most part –  Aug 25 '18 at 04:08

1 Answers1

0

In simple words:

  1. Yes they are asynchronous by default because internally based on the preemptive multitasking mechanism. That is at any point of execution a thread can be "interrupted" by execution of another thread if you don't apply explicit synchronization mechanisms (like mutex, critical section, semaphor, etc.) which makes the threads get queued into "execution queue" when they reach a point with synchronization. So yes a thread doesn't stop other threads unless they encounter the same synchronization object.

  2. An AggregateException is just a mechanism to wrap up multiple exceptions from child tasks of a parent task. A task may have child tasks if they are executed from inside of this task and if these child tasks are specified as attached all failures inside them are aggregated in the single object which can be caught at the point of the parent task waiting. Here is example of exceptions aggregation:

        var task = Task.Factory.StartNew(() =>
        {
            Console.WriteLine("Parent task");
            var subTask = Task.Factory.StartNew(
                () =>
                {
                    Console.WriteLine("Child");
                    throw new Exception("Exception in the child");
                }, TaskCreationOptions.AttachedToParent);
            throw new Exception("Exception in the parent");
        });
    
        try
        {
            task.Wait();
        }
        catch (AggregateException e)
        {
            Console.WriteLine(e);
        }
    

    The exception caught in the catch block will contain exceptions from both tasks since the child task was created with AttachedToParent option.

  3. You can think about a synchronization context as an abstraction to execute some unit of work. It actually exposes two method: Send and Post which receive some delegate to execute (synchronously or asynchronously) as an argument. By default it schedules execution of the passed delegate in thread pool in case of asynchronous semantic (Post) or just executes it directly in case synchronous semantic (Send). Why is it needed ? The abstraction gives an opportunity to provide other implementations of a unit of work execution. For example there are implementations which internally use a message pump to schedule all execution on specific thread which can be useful for UI tasks for Windows Forms or WPF. Or you can implement your own synchronization context for example in order to get some tasks sequentially executed or just make up more sophisticated scenarios. There is specific implementation of TaskScheduler called SynchronizationContextTaskScheduler which operates on top of a SynchronizationContext (i.e. schedule execution in the synchronization context) and these two abstractions provide flexible mechanism to fit any execution synchronization requirements. As a specific example of application the async/await mechanism internally uses SynchronizationContext to schedule continuations of asynchronous operations. With variety of synchronization contexts it's able to work transparently regardless of the framework it's used from (Win Forms, WPF, ASP.NET, Console App, etc.) just by using proper SynchronizationContext implementation.

Dmytro Mukalov
  • 1,949
  • 1
  • 9
  • 14
  • Thank you so much. However, when I copied (I know it's not a good idea) your AggregationException code example in to VS2017, it doesn't work. – Marc2001 Aug 25 '18 at 23:19
  • @Marc2001, I've just double checked and haven't noticed issues with the code, but maybe I overlooked something, so could you please elaborate what exactly doesn't work ? – Dmytro Mukalov Aug 26 '18 at 06:03
  • @DmytroMukalove, I have no idea either. I've seen so many examples involving this pattern. When I try the examples from all these websites, they don't work. Websites blogged that when an error occur in a task, it will wrap it in an aggregate exception. They always show examples with the same pattern just like yours but they don't work. I don't know if this is a bug or I didn't download VS2017 properly but it's very annoying – Marc2001 Aug 27 '18 at 04:52
  • @Marc2001, A clear explanation of the "doesn't work" problem will be useful. Is it compile time or run time issue. If run time what are actual results. – Dmytro Mukalov Aug 27 '18 at 05:07