locked
Different between Task t = Task.Run and Task.Factory.StartNew RRS feed

  • Question

  • Hello,
    Can someone please explain the differences to me?
    When do I take what and why?
    When do i take await, when not?

    Task.Run I need Start. If I use Task.Factory.StartNew is running immediately.
    How can I force a break and then continue without restarting?
    Thank you for good, short, understandable explanations in advance.
    I think I started a good project to see the differences.
    You can expand it to see explanations.
    If I use thread, how do i make sure it ends cleanly?
    Many greetings Markus
    using System;
    using System.Threading;
    using System.Threading.Tasks;
    
    namespace ConsoleAppTaskAsyn
    {
        public class Possibilities
        {
            public ManualResetEvent CancelThread = new ManualResetEvent(false);
    
    
            public Possibilities()
            {
    
            }
    
            public void Variant_001()
            {
                CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
                CancellationToken token = cancellationTokenSource.Token;
    
                Task t = Task.Run(async () =>
                {
                    for (int y = 0; y < 100; y++)
                    {
                        for (int x = 0; x < 100; x++)
                        {
                            while (!token.IsCancellationRequested)
                            {
                                Console.Write("*");
                                await Task.Delay(10); // for me looks is here waitung 10ms
                            }
                        }
                        Console.WriteLine();
                    }
                }, token);
    
    
                Console.WriteLine("Press Enter to stop the task");
                Console.ReadLine();
                cancellationTokenSource.Cancel();
    
                Console.WriteLine("Press Enter to exit");
                Console.ReadLine();
            }
    
    
            public void Variant_002_WithoutAsync()
            {
                CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
                CancellationToken token = cancellationTokenSource.Token;
    
                Task t = Task.Run(() =>
               {
                   for (int y = 0; y < 100; y++)
                   {
                       for (int x = 0; x < 100; x++)
                       {
                           while (!token.IsCancellationRequested)
                           {
                               Console.Write("*");
                               Task.Delay(10);  // for me looks is here not waiting 10ms
                           }
                       }
                       Console.WriteLine();
                   }
               }, token);
    
    
                Console.WriteLine("Press Enter to stop the task");
                Console.ReadLine();
                cancellationTokenSource.Cancel();
    
                Console.WriteLine("Press Enter to exit");
                Console.ReadLine();
            }
    
    
    
            public async void WorkingloopAsync(CancellationToken token)
            {
                for (int y = 0; y < 100; y++)
                {
                    for (int x = 0; x < 100; x++)
                    {
                        while (!token.IsCancellationRequested)
                        {
                            Console.Write("*");
                            await Task.Delay(10); // for me looks is here waitung 10ms
                        }
                    }
                    Console.WriteLine();
                }
            }
    
            public void WorkingloopSync(CancellationToken token)
            {
                for (int y = 0; y < 100; y++)
                {
                    for (int x = 0; x < 100; x++)
                    {
                        while (!token.IsCancellationRequested)
                        {
                            Console.Write("*");
                            Task.Delay(9000); // for me looks is here not waitung 10ms
                        }
                    }
                    Console.WriteLine();
                }
            }
    
            public void Variant_03_WithFunctionName()
            {
                CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
                CancellationToken token = cancellationTokenSource.Token;
    
    
                //Action<object> action = (object obj) =>
                //{
                //    Workingloop(token);
                //};
    
                //Action action2 = () =>
                //{
                //    WorkingloopAsync(token);
                //};
    
                Action action3 = () =>
                {
                    WorkingloopSync(token);
                };
    
                Task t = new Task(action3, token);
                t.Start();
    
                Console.WriteLine("Press Enter to stop the task");
                Console.ReadLine();
                cancellationTokenSource.Cancel();
    
                Console.WriteLine("Press Enter to exit");
                Console.ReadLine();
    
            }
    
    
            public void Variant_04_TaskFactory()
            {
                CancellationTokenSource cancellationTokenSource = new CancellationTokenSource();
                CancellationToken token = cancellationTokenSource.Token;
    
                //Action<object> action = (object obj) =>
                //{
                //    Workingloop(token);
                //};
    
                Action action2 = () =>
                {
                    WorkingloopAsync(token);
                };
    
                //Action action3 = () =>
                //{
                //    WorkingloopSync(token);
                //};
    
                //Task t = Task.Factory.StartNew(action2, token);
                Task t  = new TaskFactory(token).StartNew(action2);   is this the same es before?
    
                Console.WriteLine("Press Enter to stop the task");
                Console.ReadLine();
                cancellationTokenSource.Cancel();
    
                Console.WriteLine("Press Enter to exit");
                Console.ReadLine();
    
            }
    
            //////////////////////////////////////////  Threading ///////
    
            public void StopIt()
            {
                CancelThread.Set();
            }
    
            public void StartIt()
            {
                var thread = new Thread(DoSomething);
                thread.IsBackground = true;
    
                //Ensure terminate event is reset
                CancelThread.Reset();
    
                thread.Start();
    
                ///-------
                ///
                //Thread t = new Thread(DoSomething_2);
                //t.Start(this);
    
                Thread thread2 = new Thread(() => DoSomething_2(this));
                thread2.Start();
    
    
            }
    
            private void DoSomething()
            {
                Thread.CurrentThread.Name = "MyThread.DoSomething-" + Thread.CurrentThread.ManagedThreadId;
    
                for (int i = 0; i < 10000; i++)
                {
                    Console.Write("*AAAAAAA*");
                    Thread.Sleep(100);
                    if (CancelThread.WaitOne(0))
                        return;
                }
            }
    
            private void DoSomething_2(object parameter)
            {
                Thread.CurrentThread.Name = "MyThread.DoSomething_2-" + Thread.CurrentThread.ManagedThreadId;
    
                Possibilities whatYouWant = parameter as Possibilities;
    
                for (int i = 0; i < 10000; i++)
                {
                    Console.Write("*BBBBBBB*");
                    Thread.Sleep(100);
                    if (CancelThread.WaitOne(0))
                        return;
                }
            }
        }
    
        /// <summary>
        /// Thread with event
        /// </summary>
    
        class Program
        {
            static void Main(string[] args)
            {
                Possibilities test = new Possibilities();
    
                // test.Variant_001();
                // test.Variant_002_WithoutAsync();
                // test.Variant_03_WithFunctionName();
                test.Variant_04_TaskFactory();
    
    
                Console.WriteLine("####### Now with Thread ####### ");
                Console.ReadLine();
                Console.WriteLine("####### Press Enter for START ####### ");
                Console.ReadLine();
                test.StartIt();
                Console.WriteLine("####### Thread is started ####### ");
    
                Console.WriteLine("####### Press Enter for STOP ####### ");
                Console.ReadLine();
                test.StopIt();
    
               
                Console.WriteLine("####### Thread is stopped  ####### ");
    
                Console.ReadLine();
            }
        }
    
    }

    Tuesday, January 22, 2019 5:08 PM

Answers

  • Hi Markus Freitag,

    >>When do i take await, when not

    Await is used with async not Task. Task has wait method.

    >>How can I force a break and then continue without restarting?

    You could use CancellationTokenSource to stop Task. Please check the link below.

    https://binary-studio.com/2015/10/23/task-cancellation-in-c-and-things-you-should-know-about-it/

    A task may be started and run only once. Any attempts to schedule a task a second time will result in an exception. We do not suggest to restart, please create a new task.

    >>If I use thread, how do i make sure it ends cleanly?

    1) Use a callback. The thread when ends raise an event and you in the event method do whatever you like. Look for Callback in MSDN.

    2) Set a property in the class containing the thread method. For example you can have a private Boolean IsFinished = false; and then as last line of the thread you call a this.IsFinished = true; If someone somewhere wants to know if it's finished just look at the variable value.

    Anyway, I think also the new parallel C# framework is a very good hint.

    Best Regards,

    Wendy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by Markus Freitag Wednesday, January 30, 2019 5:12 PM
    Wednesday, January 30, 2019 6:26 AM

All replies

  • Hi Markus Freitag,

    Thank you for posting here.

    For your question, in the .NET Framework 4.5 Developer Preview, we’ve introduced the new Task.Run method.  This in no way obsoletes Task.Factory.StartNew, but rather should simply be thought of as a quick way to use Task.Factory.StartNew without needing to specify a bunch of parameters.  It’s a shortcut.  In fact, Task.Run is actually implemented in terms of the same logic used for Task.Factory.StartNew, just passing in some default parameters.

    For more details, you could refer to the blog below.

    https://blogs.msdn.microsoft.com/pfxteam/2011/10/24/task-run-vs-task-factory-startnew/

    Best Regards,

    Wendy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, January 23, 2019 6:52 AM
  • Hello Wendy,

    In .NET 4, Task.Factory.StartNew was the primary method for scheduling a new task. 
    Many overloads provided for a highly configurable mechanism, enabling setting options,
    passing in arbitrary state, enabling cancellation, and even controlling scheduling
    behaviors.  The flip side of all of this power is complexity.  You need to know when
     to use which overload, what scheduler to provide, and the like.
     And “Task.Factory.StartNew” doesn’t exactly roll off the tongue, at least not
     quickly enough for something that’s used in such primary scenarios as easily
     offloading work to background processing threads.

    So, in the .NET Framework 4.5 Developer Preview, we’ve introduced the new Task.Run
    method.  This in no way obsoletes Task.Factory.StartNew, but rather should simply be
    thought of as a quick way to use Task.Factory.StartNew without needing to specify a
    bunch of parameters.  It’s a shortcut.  In fact, Task.Run is actually implemented
    in terms of the same logic used for Task.Factory.StartNew, just passing in some
    default parameters.  When you pass an Action to Task.Run:

    So for me the new Task.Run method is important.
    For me I should use the new method. There are so many possibilities that I don't understand it.
    Couldn't the experts (developers from core/framework) have made it easier, more readable?
    Could you experts in the forum give an explanation to these questions?
    How can I force a break and then continue without restarting?
    If I use thread, how do i make sure it ends cleanly?
    Many Greetings Markus
    Wednesday, January 23, 2019 5:30 PM
  • Hi Markus Freitag,

    >>When do i take await, when not

    Await is used with async not Task. Task has wait method.

    >>How can I force a break and then continue without restarting?

    You could use CancellationTokenSource to stop Task. Please check the link below.

    https://binary-studio.com/2015/10/23/task-cancellation-in-c-and-things-you-should-know-about-it/

    A task may be started and run only once. Any attempts to schedule a task a second time will result in an exception. We do not suggest to restart, please create a new task.

    >>If I use thread, how do i make sure it ends cleanly?

    1) Use a callback. The thread when ends raise an event and you in the event method do whatever you like. Look for Callback in MSDN.

    2) Set a property in the class containing the thread method. For example you can have a private Boolean IsFinished = false; and then as last line of the thread you call a this.IsFinished = true; If someone somewhere wants to know if it's finished just look at the variable value.

    Anyway, I think also the new parallel C# framework is a very good hint.

    Best Regards,

    Wendy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • Marked as answer by Markus Freitag Wednesday, January 30, 2019 5:12 PM
    Wednesday, January 30, 2019 6:26 AM