What is Task.RunSynchronously for?

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP











up vote
8
down vote

favorite
1












I just wonder what's the method for? In what kind of scenario I can use this method.



My initial thought is RunSynchronously is for calling an async method and running that synchronously without causing a deadlock issue like what .wait() does.



However, according to MSDN,




Ordinarily, tasks are executed asynchronously on a thread pool thread and do not block the calling thread. Tasks executed by calling the RunSynchronously() method are associated with the current TaskScheduler and are run on the calling thread. If the target scheduler does not support running this task on the calling thread, the task will be scheduled for execution on the schedule, and the calling thread will block until the task has completed execution




Why need a TaskScheduler here, if the task going to run on the calling thread?










share|improve this question



















  • 3




    Looks like it will let the scheduler decide when to run it rather than running it immediately on the current thread from the description you copied. Scheduler will make a decision here instead of just running it synchronously immediately.
    – Stefano d'Antonio
    5 hours ago






  • 2




    It wouldn't be of any use with most async methods since they return "hot" Tasks (i.e. already running) You can only use Run or RunSynchronously with "cold" Tasks that haven't started yet.
    – Damien_The_Unbeliever
    5 hours ago






  • 3




    Stephen Cleary blog seems to have it covered. The disclaimer at the top is interesting There is absolutely nothing in this blog post that is recommended for modern code. If you’re looking for best practices, move along; there’s nothing to see here. So it seems legacy
    – Liam
    5 hours ago







  • 2




    Method RunSynchronously was created before async await flow was introduced in .NET 4.5, apparently the idea was to allow executing of 'cold' tasks synchronously with an attempt of using the same thread context, and specified scheduler. Same as .StartNew() it's obsolete. There is no point in using it unless you need to create a cold task and run it in a current thread synchronously, using the current TaskScheduler.
    – Fabjan
    4 hours ago







  • 1




    @Fabjan there's one tiny case for both, since they accept a TaskScheduler parameter. If you want to use a custom scheduler, eg a limeted DOP scheduler. Even then, there are better options like an ActionBlock<> with a limited DOP
    – Panagiotis Kanavos
    4 hours ago















up vote
8
down vote

favorite
1












I just wonder what's the method for? In what kind of scenario I can use this method.



My initial thought is RunSynchronously is for calling an async method and running that synchronously without causing a deadlock issue like what .wait() does.



However, according to MSDN,




Ordinarily, tasks are executed asynchronously on a thread pool thread and do not block the calling thread. Tasks executed by calling the RunSynchronously() method are associated with the current TaskScheduler and are run on the calling thread. If the target scheduler does not support running this task on the calling thread, the task will be scheduled for execution on the schedule, and the calling thread will block until the task has completed execution




Why need a TaskScheduler here, if the task going to run on the calling thread?










share|improve this question



















  • 3




    Looks like it will let the scheduler decide when to run it rather than running it immediately on the current thread from the description you copied. Scheduler will make a decision here instead of just running it synchronously immediately.
    – Stefano d'Antonio
    5 hours ago






  • 2




    It wouldn't be of any use with most async methods since they return "hot" Tasks (i.e. already running) You can only use Run or RunSynchronously with "cold" Tasks that haven't started yet.
    – Damien_The_Unbeliever
    5 hours ago






  • 3




    Stephen Cleary blog seems to have it covered. The disclaimer at the top is interesting There is absolutely nothing in this blog post that is recommended for modern code. If you’re looking for best practices, move along; there’s nothing to see here. So it seems legacy
    – Liam
    5 hours ago







  • 2




    Method RunSynchronously was created before async await flow was introduced in .NET 4.5, apparently the idea was to allow executing of 'cold' tasks synchronously with an attempt of using the same thread context, and specified scheduler. Same as .StartNew() it's obsolete. There is no point in using it unless you need to create a cold task and run it in a current thread synchronously, using the current TaskScheduler.
    – Fabjan
    4 hours ago







  • 1




    @Fabjan there's one tiny case for both, since they accept a TaskScheduler parameter. If you want to use a custom scheduler, eg a limeted DOP scheduler. Even then, there are better options like an ActionBlock<> with a limited DOP
    – Panagiotis Kanavos
    4 hours ago













up vote
8
down vote

favorite
1









up vote
8
down vote

favorite
1






1





I just wonder what's the method for? In what kind of scenario I can use this method.



My initial thought is RunSynchronously is for calling an async method and running that synchronously without causing a deadlock issue like what .wait() does.



However, according to MSDN,




Ordinarily, tasks are executed asynchronously on a thread pool thread and do not block the calling thread. Tasks executed by calling the RunSynchronously() method are associated with the current TaskScheduler and are run on the calling thread. If the target scheduler does not support running this task on the calling thread, the task will be scheduled for execution on the schedule, and the calling thread will block until the task has completed execution




Why need a TaskScheduler here, if the task going to run on the calling thread?










share|improve this question















I just wonder what's the method for? In what kind of scenario I can use this method.



My initial thought is RunSynchronously is for calling an async method and running that synchronously without causing a deadlock issue like what .wait() does.



However, according to MSDN,




Ordinarily, tasks are executed asynchronously on a thread pool thread and do not block the calling thread. Tasks executed by calling the RunSynchronously() method are associated with the current TaskScheduler and are run on the calling thread. If the target scheduler does not support running this task on the calling thread, the task will be scheduled for execution on the schedule, and the calling thread will block until the task has completed execution




Why need a TaskScheduler here, if the task going to run on the calling thread?







c# multithreading asynchronous






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited 5 hours ago









JoenSo

113




113










asked 5 hours ago









ValidfroM

1,34221635




1,34221635







  • 3




    Looks like it will let the scheduler decide when to run it rather than running it immediately on the current thread from the description you copied. Scheduler will make a decision here instead of just running it synchronously immediately.
    – Stefano d'Antonio
    5 hours ago






  • 2




    It wouldn't be of any use with most async methods since they return "hot" Tasks (i.e. already running) You can only use Run or RunSynchronously with "cold" Tasks that haven't started yet.
    – Damien_The_Unbeliever
    5 hours ago






  • 3




    Stephen Cleary blog seems to have it covered. The disclaimer at the top is interesting There is absolutely nothing in this blog post that is recommended for modern code. If you’re looking for best practices, move along; there’s nothing to see here. So it seems legacy
    – Liam
    5 hours ago







  • 2




    Method RunSynchronously was created before async await flow was introduced in .NET 4.5, apparently the idea was to allow executing of 'cold' tasks synchronously with an attempt of using the same thread context, and specified scheduler. Same as .StartNew() it's obsolete. There is no point in using it unless you need to create a cold task and run it in a current thread synchronously, using the current TaskScheduler.
    – Fabjan
    4 hours ago







  • 1




    @Fabjan there's one tiny case for both, since they accept a TaskScheduler parameter. If you want to use a custom scheduler, eg a limeted DOP scheduler. Even then, there are better options like an ActionBlock<> with a limited DOP
    – Panagiotis Kanavos
    4 hours ago













  • 3




    Looks like it will let the scheduler decide when to run it rather than running it immediately on the current thread from the description you copied. Scheduler will make a decision here instead of just running it synchronously immediately.
    – Stefano d'Antonio
    5 hours ago






  • 2




    It wouldn't be of any use with most async methods since they return "hot" Tasks (i.e. already running) You can only use Run or RunSynchronously with "cold" Tasks that haven't started yet.
    – Damien_The_Unbeliever
    5 hours ago






  • 3




    Stephen Cleary blog seems to have it covered. The disclaimer at the top is interesting There is absolutely nothing in this blog post that is recommended for modern code. If you’re looking for best practices, move along; there’s nothing to see here. So it seems legacy
    – Liam
    5 hours ago







  • 2




    Method RunSynchronously was created before async await flow was introduced in .NET 4.5, apparently the idea was to allow executing of 'cold' tasks synchronously with an attempt of using the same thread context, and specified scheduler. Same as .StartNew() it's obsolete. There is no point in using it unless you need to create a cold task and run it in a current thread synchronously, using the current TaskScheduler.
    – Fabjan
    4 hours ago







  • 1




    @Fabjan there's one tiny case for both, since they accept a TaskScheduler parameter. If you want to use a custom scheduler, eg a limeted DOP scheduler. Even then, there are better options like an ActionBlock<> with a limited DOP
    – Panagiotis Kanavos
    4 hours ago








3




3




Looks like it will let the scheduler decide when to run it rather than running it immediately on the current thread from the description you copied. Scheduler will make a decision here instead of just running it synchronously immediately.
– Stefano d'Antonio
5 hours ago




Looks like it will let the scheduler decide when to run it rather than running it immediately on the current thread from the description you copied. Scheduler will make a decision here instead of just running it synchronously immediately.
– Stefano d'Antonio
5 hours ago




2




2




It wouldn't be of any use with most async methods since they return "hot" Tasks (i.e. already running) You can only use Run or RunSynchronously with "cold" Tasks that haven't started yet.
– Damien_The_Unbeliever
5 hours ago




It wouldn't be of any use with most async methods since they return "hot" Tasks (i.e. already running) You can only use Run or RunSynchronously with "cold" Tasks that haven't started yet.
– Damien_The_Unbeliever
5 hours ago




3




3




Stephen Cleary blog seems to have it covered. The disclaimer at the top is interesting There is absolutely nothing in this blog post that is recommended for modern code. If you’re looking for best practices, move along; there’s nothing to see here. So it seems legacy
– Liam
5 hours ago





Stephen Cleary blog seems to have it covered. The disclaimer at the top is interesting There is absolutely nothing in this blog post that is recommended for modern code. If you’re looking for best practices, move along; there’s nothing to see here. So it seems legacy
– Liam
5 hours ago





2




2




Method RunSynchronously was created before async await flow was introduced in .NET 4.5, apparently the idea was to allow executing of 'cold' tasks synchronously with an attempt of using the same thread context, and specified scheduler. Same as .StartNew() it's obsolete. There is no point in using it unless you need to create a cold task and run it in a current thread synchronously, using the current TaskScheduler.
– Fabjan
4 hours ago





Method RunSynchronously was created before async await flow was introduced in .NET 4.5, apparently the idea was to allow executing of 'cold' tasks synchronously with an attempt of using the same thread context, and specified scheduler. Same as .StartNew() it's obsolete. There is no point in using it unless you need to create a cold task and run it in a current thread synchronously, using the current TaskScheduler.
– Fabjan
4 hours ago





1




1




@Fabjan there's one tiny case for both, since they accept a TaskScheduler parameter. If you want to use a custom scheduler, eg a limeted DOP scheduler. Even then, there are better options like an ActionBlock<> with a limited DOP
– Panagiotis Kanavos
4 hours ago





@Fabjan there's one tiny case for both, since they accept a TaskScheduler parameter. If you want to use a custom scheduler, eg a limeted DOP scheduler. Even then, there are better options like an ActionBlock<> with a limited DOP
– Panagiotis Kanavos
4 hours ago













2 Answers
2






active

oldest

votes

















up vote
7
down vote



accepted










RunSynchronously delegates the decision of when to start the task to the current task scheduler (or the one passed as argument).



I am not sure why it is there (maybe for internal or legacy use), but it is hard to think of a useful use case in the current versions of .NET. @Fabjan has a possible explanation in his comment to the question.



RunSynchronously asks the scheduler to run it synchronously but then the scheduler could very well ignore the hint and run it in a thread pool thread and your current thread will synchronously block until it is completed.



The scheduler does not have to run it on the current thread and does not have to run it immediately although I think it is what will happen on common schedulers (ThreadPoolTaskScheduler and common UI schedulers).



RunSynchronously will also throw an exception if the task has already been started or is completed/faulted (this means you will not be able to use it on async methods).



This code may clarify the different behaviour:



Wait and Result don't run the task at all, they just wait for the task completion on the current thread and block it until the completion so if we want to compare, we can compare Start and Wait to RunSynchronously:



class Scheduler : TaskScheduler

protected override void QueueTask(Task task) =>
Console.WriteLine("QueueTask");

protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)

Console.WriteLine("TryExecuteTaskInline");

return false;


protected override IEnumerable<Task> GetScheduledTasks() => throw new NotImplementedException();


static class Program

static void Main()

var taskToStart = new Task(() => );
var taskToRunSynchronously = new Task(() => );

taskToStart.Start(new Scheduler());
taskToRunSynchronously.RunSynchronously(new Scheduler());




If you try and comment Start or RunSynchronously and run the code, you will see that Start tries and queue the task to the scheduler while RunSynchronously will try and execute it inline and if failing (return false), it will just queue it.






share|improve this answer





























    up vote
    4
    down vote













    First let's have a look into this code:



    public async static Task<int> MyAsyncMethod()

    await Task.Delay(100);
    return 100;


    //Task.Delay(5000).RunSynchronously(); // bang
    //Task.Run(() => Thread.Sleep(5000)).RunSynchronously(); // bang
    // MyAsyncMethod().RunSynchronously(); // bang

    var t = new Task(() => Thread.Sleep(5000));
    t.RunSynchronously(); // works


    In this example we've tried to invoke RunSynchronously on task that:



    • Returns other Task with result (promise task)

    • Is a 'hot' task

    • Another promise task created by async await

    • 'Cold' task with delegate

    What statuses will they have after creation ?



    • Waiting for activation

    • WaitingToRun

    • WaitingForActivation

    • Created

    All 'hot' tasks are created with status WaitingForActivationor WaitingToRun and are associated with a task scheduler.



    Method RunSynchronously only knows how to work with 'cold' tasks that contain delegate and that have status of Created.



    Conclusion:



    The method RunSynchronously had probably appeared when there were no 'hot' tasks or they hadn't been extensively used and was created for a specific purpose.



    In case we need a 'cold' task with custom TaskScheduler then method RunSynchronously might be a way to go otherwise it's an outdated method that most of developers (including me) would most likely ignore.



    For running a 'hot' task synchronously (which we should avoid at all cost) we could do task.GetAwaiter().GetResult(). As a bonus it will return original exception and not AggregateException.






    share|improve this answer






















    • It's probably worth noting that Thread has (basically) been superseded with Task (Task.Delay()) so Thread.Sleep could be considered legacy too now. Which is why it works with the legacy RunSynchronously
      – Liam
      4 hours ago










    Your Answer





    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    convertImagesToLinks: true,
    noModals: false,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













     

    draft saved


    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52759608%2fwhat-is-task-runsynchronously-for%23new-answer', 'question_page');

    );

    Post as a guest






























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes








    up vote
    7
    down vote



    accepted










    RunSynchronously delegates the decision of when to start the task to the current task scheduler (or the one passed as argument).



    I am not sure why it is there (maybe for internal or legacy use), but it is hard to think of a useful use case in the current versions of .NET. @Fabjan has a possible explanation in his comment to the question.



    RunSynchronously asks the scheduler to run it synchronously but then the scheduler could very well ignore the hint and run it in a thread pool thread and your current thread will synchronously block until it is completed.



    The scheduler does not have to run it on the current thread and does not have to run it immediately although I think it is what will happen on common schedulers (ThreadPoolTaskScheduler and common UI schedulers).



    RunSynchronously will also throw an exception if the task has already been started or is completed/faulted (this means you will not be able to use it on async methods).



    This code may clarify the different behaviour:



    Wait and Result don't run the task at all, they just wait for the task completion on the current thread and block it until the completion so if we want to compare, we can compare Start and Wait to RunSynchronously:



    class Scheduler : TaskScheduler

    protected override void QueueTask(Task task) =>
    Console.WriteLine("QueueTask");

    protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)

    Console.WriteLine("TryExecuteTaskInline");

    return false;


    protected override IEnumerable<Task> GetScheduledTasks() => throw new NotImplementedException();


    static class Program

    static void Main()

    var taskToStart = new Task(() => );
    var taskToRunSynchronously = new Task(() => );

    taskToStart.Start(new Scheduler());
    taskToRunSynchronously.RunSynchronously(new Scheduler());




    If you try and comment Start or RunSynchronously and run the code, you will see that Start tries and queue the task to the scheduler while RunSynchronously will try and execute it inline and if failing (return false), it will just queue it.






    share|improve this answer


























      up vote
      7
      down vote



      accepted










      RunSynchronously delegates the decision of when to start the task to the current task scheduler (or the one passed as argument).



      I am not sure why it is there (maybe for internal or legacy use), but it is hard to think of a useful use case in the current versions of .NET. @Fabjan has a possible explanation in his comment to the question.



      RunSynchronously asks the scheduler to run it synchronously but then the scheduler could very well ignore the hint and run it in a thread pool thread and your current thread will synchronously block until it is completed.



      The scheduler does not have to run it on the current thread and does not have to run it immediately although I think it is what will happen on common schedulers (ThreadPoolTaskScheduler and common UI schedulers).



      RunSynchronously will also throw an exception if the task has already been started or is completed/faulted (this means you will not be able to use it on async methods).



      This code may clarify the different behaviour:



      Wait and Result don't run the task at all, they just wait for the task completion on the current thread and block it until the completion so if we want to compare, we can compare Start and Wait to RunSynchronously:



      class Scheduler : TaskScheduler

      protected override void QueueTask(Task task) =>
      Console.WriteLine("QueueTask");

      protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)

      Console.WriteLine("TryExecuteTaskInline");

      return false;


      protected override IEnumerable<Task> GetScheduledTasks() => throw new NotImplementedException();


      static class Program

      static void Main()

      var taskToStart = new Task(() => );
      var taskToRunSynchronously = new Task(() => );

      taskToStart.Start(new Scheduler());
      taskToRunSynchronously.RunSynchronously(new Scheduler());




      If you try and comment Start or RunSynchronously and run the code, you will see that Start tries and queue the task to the scheduler while RunSynchronously will try and execute it inline and if failing (return false), it will just queue it.






      share|improve this answer
























        up vote
        7
        down vote



        accepted







        up vote
        7
        down vote



        accepted






        RunSynchronously delegates the decision of when to start the task to the current task scheduler (or the one passed as argument).



        I am not sure why it is there (maybe for internal or legacy use), but it is hard to think of a useful use case in the current versions of .NET. @Fabjan has a possible explanation in his comment to the question.



        RunSynchronously asks the scheduler to run it synchronously but then the scheduler could very well ignore the hint and run it in a thread pool thread and your current thread will synchronously block until it is completed.



        The scheduler does not have to run it on the current thread and does not have to run it immediately although I think it is what will happen on common schedulers (ThreadPoolTaskScheduler and common UI schedulers).



        RunSynchronously will also throw an exception if the task has already been started or is completed/faulted (this means you will not be able to use it on async methods).



        This code may clarify the different behaviour:



        Wait and Result don't run the task at all, they just wait for the task completion on the current thread and block it until the completion so if we want to compare, we can compare Start and Wait to RunSynchronously:



        class Scheduler : TaskScheduler

        protected override void QueueTask(Task task) =>
        Console.WriteLine("QueueTask");

        protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)

        Console.WriteLine("TryExecuteTaskInline");

        return false;


        protected override IEnumerable<Task> GetScheduledTasks() => throw new NotImplementedException();


        static class Program

        static void Main()

        var taskToStart = new Task(() => );
        var taskToRunSynchronously = new Task(() => );

        taskToStart.Start(new Scheduler());
        taskToRunSynchronously.RunSynchronously(new Scheduler());




        If you try and comment Start or RunSynchronously and run the code, you will see that Start tries and queue the task to the scheduler while RunSynchronously will try and execute it inline and if failing (return false), it will just queue it.






        share|improve this answer














        RunSynchronously delegates the decision of when to start the task to the current task scheduler (or the one passed as argument).



        I am not sure why it is there (maybe for internal or legacy use), but it is hard to think of a useful use case in the current versions of .NET. @Fabjan has a possible explanation in his comment to the question.



        RunSynchronously asks the scheduler to run it synchronously but then the scheduler could very well ignore the hint and run it in a thread pool thread and your current thread will synchronously block until it is completed.



        The scheduler does not have to run it on the current thread and does not have to run it immediately although I think it is what will happen on common schedulers (ThreadPoolTaskScheduler and common UI schedulers).



        RunSynchronously will also throw an exception if the task has already been started or is completed/faulted (this means you will not be able to use it on async methods).



        This code may clarify the different behaviour:



        Wait and Result don't run the task at all, they just wait for the task completion on the current thread and block it until the completion so if we want to compare, we can compare Start and Wait to RunSynchronously:



        class Scheduler : TaskScheduler

        protected override void QueueTask(Task task) =>
        Console.WriteLine("QueueTask");

        protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)

        Console.WriteLine("TryExecuteTaskInline");

        return false;


        protected override IEnumerable<Task> GetScheduledTasks() => throw new NotImplementedException();


        static class Program

        static void Main()

        var taskToStart = new Task(() => );
        var taskToRunSynchronously = new Task(() => );

        taskToStart.Start(new Scheduler());
        taskToRunSynchronously.RunSynchronously(new Scheduler());




        If you try and comment Start or RunSynchronously and run the code, you will see that Start tries and queue the task to the scheduler while RunSynchronously will try and execute it inline and if failing (return false), it will just queue it.







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited 4 hours ago









        Liam

        15.5k1575125




        15.5k1575125










        answered 4 hours ago









        Stefano d'Antonio

        3,60011632




        3,60011632






















            up vote
            4
            down vote













            First let's have a look into this code:



            public async static Task<int> MyAsyncMethod()

            await Task.Delay(100);
            return 100;


            //Task.Delay(5000).RunSynchronously(); // bang
            //Task.Run(() => Thread.Sleep(5000)).RunSynchronously(); // bang
            // MyAsyncMethod().RunSynchronously(); // bang

            var t = new Task(() => Thread.Sleep(5000));
            t.RunSynchronously(); // works


            In this example we've tried to invoke RunSynchronously on task that:



            • Returns other Task with result (promise task)

            • Is a 'hot' task

            • Another promise task created by async await

            • 'Cold' task with delegate

            What statuses will they have after creation ?



            • Waiting for activation

            • WaitingToRun

            • WaitingForActivation

            • Created

            All 'hot' tasks are created with status WaitingForActivationor WaitingToRun and are associated with a task scheduler.



            Method RunSynchronously only knows how to work with 'cold' tasks that contain delegate and that have status of Created.



            Conclusion:



            The method RunSynchronously had probably appeared when there were no 'hot' tasks or they hadn't been extensively used and was created for a specific purpose.



            In case we need a 'cold' task with custom TaskScheduler then method RunSynchronously might be a way to go otherwise it's an outdated method that most of developers (including me) would most likely ignore.



            For running a 'hot' task synchronously (which we should avoid at all cost) we could do task.GetAwaiter().GetResult(). As a bonus it will return original exception and not AggregateException.






            share|improve this answer






















            • It's probably worth noting that Thread has (basically) been superseded with Task (Task.Delay()) so Thread.Sleep could be considered legacy too now. Which is why it works with the legacy RunSynchronously
              – Liam
              4 hours ago














            up vote
            4
            down vote













            First let's have a look into this code:



            public async static Task<int> MyAsyncMethod()

            await Task.Delay(100);
            return 100;


            //Task.Delay(5000).RunSynchronously(); // bang
            //Task.Run(() => Thread.Sleep(5000)).RunSynchronously(); // bang
            // MyAsyncMethod().RunSynchronously(); // bang

            var t = new Task(() => Thread.Sleep(5000));
            t.RunSynchronously(); // works


            In this example we've tried to invoke RunSynchronously on task that:



            • Returns other Task with result (promise task)

            • Is a 'hot' task

            • Another promise task created by async await

            • 'Cold' task with delegate

            What statuses will they have after creation ?



            • Waiting for activation

            • WaitingToRun

            • WaitingForActivation

            • Created

            All 'hot' tasks are created with status WaitingForActivationor WaitingToRun and are associated with a task scheduler.



            Method RunSynchronously only knows how to work with 'cold' tasks that contain delegate and that have status of Created.



            Conclusion:



            The method RunSynchronously had probably appeared when there were no 'hot' tasks or they hadn't been extensively used and was created for a specific purpose.



            In case we need a 'cold' task with custom TaskScheduler then method RunSynchronously might be a way to go otherwise it's an outdated method that most of developers (including me) would most likely ignore.



            For running a 'hot' task synchronously (which we should avoid at all cost) we could do task.GetAwaiter().GetResult(). As a bonus it will return original exception and not AggregateException.






            share|improve this answer






















            • It's probably worth noting that Thread has (basically) been superseded with Task (Task.Delay()) so Thread.Sleep could be considered legacy too now. Which is why it works with the legacy RunSynchronously
              – Liam
              4 hours ago












            up vote
            4
            down vote










            up vote
            4
            down vote









            First let's have a look into this code:



            public async static Task<int> MyAsyncMethod()

            await Task.Delay(100);
            return 100;


            //Task.Delay(5000).RunSynchronously(); // bang
            //Task.Run(() => Thread.Sleep(5000)).RunSynchronously(); // bang
            // MyAsyncMethod().RunSynchronously(); // bang

            var t = new Task(() => Thread.Sleep(5000));
            t.RunSynchronously(); // works


            In this example we've tried to invoke RunSynchronously on task that:



            • Returns other Task with result (promise task)

            • Is a 'hot' task

            • Another promise task created by async await

            • 'Cold' task with delegate

            What statuses will they have after creation ?



            • Waiting for activation

            • WaitingToRun

            • WaitingForActivation

            • Created

            All 'hot' tasks are created with status WaitingForActivationor WaitingToRun and are associated with a task scheduler.



            Method RunSynchronously only knows how to work with 'cold' tasks that contain delegate and that have status of Created.



            Conclusion:



            The method RunSynchronously had probably appeared when there were no 'hot' tasks or they hadn't been extensively used and was created for a specific purpose.



            In case we need a 'cold' task with custom TaskScheduler then method RunSynchronously might be a way to go otherwise it's an outdated method that most of developers (including me) would most likely ignore.



            For running a 'hot' task synchronously (which we should avoid at all cost) we could do task.GetAwaiter().GetResult(). As a bonus it will return original exception and not AggregateException.






            share|improve this answer














            First let's have a look into this code:



            public async static Task<int> MyAsyncMethod()

            await Task.Delay(100);
            return 100;


            //Task.Delay(5000).RunSynchronously(); // bang
            //Task.Run(() => Thread.Sleep(5000)).RunSynchronously(); // bang
            // MyAsyncMethod().RunSynchronously(); // bang

            var t = new Task(() => Thread.Sleep(5000));
            t.RunSynchronously(); // works


            In this example we've tried to invoke RunSynchronously on task that:



            • Returns other Task with result (promise task)

            • Is a 'hot' task

            • Another promise task created by async await

            • 'Cold' task with delegate

            What statuses will they have after creation ?



            • Waiting for activation

            • WaitingToRun

            • WaitingForActivation

            • Created

            All 'hot' tasks are created with status WaitingForActivationor WaitingToRun and are associated with a task scheduler.



            Method RunSynchronously only knows how to work with 'cold' tasks that contain delegate and that have status of Created.



            Conclusion:



            The method RunSynchronously had probably appeared when there were no 'hot' tasks or they hadn't been extensively used and was created for a specific purpose.



            In case we need a 'cold' task with custom TaskScheduler then method RunSynchronously might be a way to go otherwise it's an outdated method that most of developers (including me) would most likely ignore.



            For running a 'hot' task synchronously (which we should avoid at all cost) we could do task.GetAwaiter().GetResult(). As a bonus it will return original exception and not AggregateException.







            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited 3 hours ago

























            answered 4 hours ago









            Fabjan

            8,76421438




            8,76421438











            • It's probably worth noting that Thread has (basically) been superseded with Task (Task.Delay()) so Thread.Sleep could be considered legacy too now. Which is why it works with the legacy RunSynchronously
              – Liam
              4 hours ago
















            • It's probably worth noting that Thread has (basically) been superseded with Task (Task.Delay()) so Thread.Sleep could be considered legacy too now. Which is why it works with the legacy RunSynchronously
              – Liam
              4 hours ago















            It's probably worth noting that Thread has (basically) been superseded with Task (Task.Delay()) so Thread.Sleep could be considered legacy too now. Which is why it works with the legacy RunSynchronously
            – Liam
            4 hours ago




            It's probably worth noting that Thread has (basically) been superseded with Task (Task.Delay()) so Thread.Sleep could be considered legacy too now. Which is why it works with the legacy RunSynchronously
            – Liam
            4 hours ago

















             

            draft saved


            draft discarded















































             


            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52759608%2fwhat-is-task-runsynchronously-for%23new-answer', 'question_page');

            );

            Post as a guest













































































            Comments

            Popular posts from this blog

            Long meetings (6-7 hours a day): Being “babysat” by supervisor

            What does second last employer means? [closed]

            One-line joke