none
Using task await and Task.FromResult properly - any issues predicted RRS feed

  • Question

  • Hi all

    I created this code with the help of asking question in forum. The main purpose of the code is to read values from 6 functions at the same times. I am using an external library functions as the code actually talks to the data acquisition software. 

    using IMLtools;
    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Threading.Tasks;
    using System.Timers;
    using System.Configuration;
    
    
    
    
    
    namespace ConsoleApp12
    {
        class Program
        {
            static Logger testlogger = new Logger();
            static IMLtoolsv6 newsd = new IMLtoolsv6();
            static int tableWidth = 180;
            static Timer aTimer;
    
    
         
            static string channel1 = ConfigurationManager.AppSettings["channel1name"];
            static string channel2 = ConfigurationManager.AppSettings["channel2name"];
            static string channel3 = ConfigurationManager.AppSettings["channel3name"];
            static string channel4 = ConfigurationManager.AppSettings["channel4name"];
            static string channel5 = ConfigurationManager.AppSettings["channel5name"];
            static string channel6 = ConfigurationManager.AppSettings["channel6name"];
    
            static void Main(string[] args)
            {
             
    
                string IMSfilespec = "C:\\Windmill\\setups\\NEWCONFI.IMS";
                string IMSname = "NEWCONFI.IMS";
    
                try
                {
                    newsd.IMLOpen();
                    newsd.IMSLoadFile(IMSfilespec, IMSname);
                    testlogger.Log("Successful connection to IMS");
                }
                catch(Exception ex)
                {
                    testlogger.Log(ex.ToString());
                }
                  
    
                PrintLine();
                PrintRow("Time","Channel 1","Channel 2", "Channel 3", "Channel 4", "Channel 5","Channel 6");
                PrintLine();
                SetTimer();
    
               
            }
    
            
    
            private static void PrintLine()
            {
                Console.WriteLine(new string('-', tableWidth));
            }
    
            static void PrintRow(params string[] columns)
            {
                int width = (tableWidth - columns.Length) / columns.Length;
                string row = "|";
    
                foreach (string column in columns)
                {
                    row += AlignCentre(column, width) + "|";
                  
                }
    
                Console.WriteLine(row);
            }
    
            static string AlignCentre(string text, int width)
            {
                text = text.Length > width ? text.Substring(0, width - 3) + "..." : text;
    
                if (string.IsNullOrEmpty(text))
                {
                    return new string(' ', width);
                }
                else
                {
                    return text.PadRight(width - (width - text.Length) / 2).PadLeft(width);
                }
            }
    
            private static void SetTimer()
            {
                try
                {
                    aTimer = new Timer();
                    aTimer.Elapsed += OnTimedEvent;
                    aTimer.Interval = 1000;
                    aTimer.Enabled = true;
                    Console.ReadKey();
                }
                // Create a timer with a two second interval.
                catch (Exception ex)
                {
                    testlogger.Log(ex.ToString());
                }
            }
    
            public static async void OnTimedEvent(Object source, ElapsedEventArgs e)
            {
    
                //Task<string> task1 = Task.Run(() => readChannel1());
                //task1.Wait();
                //Task<string> task2 = Task.Run(() => readChannel2());
                //task2.Wait();
                //Task<string> task3 = Task.Run(() => readChannel3());
                //task3.Wait();
                //Task<string> task4 = Task.Run(() => readChannel4());
                //task4.Wait();
                //Task<string> task5 = Task.Run(() => readChannel5());
                //task5.Wait();
                //Task<string> task6 = Task.Run(() => readChannel6());
                //task6.Wait();
                try
                {
                    Task<string> task1 = readChannel1();
                    task1.Wait();
                    Task<string> task2 = readChannel2();
                    task2.Wait();
                    Task<string> task3 = readChannel3();
                    task3.Wait();
                    Task<string> task4 = readChannel4();
                    task4.Wait();
                    Task<string> task5 = readChannel5();
                    task5.Wait();
                    Task<string> task6 = readChannel6();
                    task6.Wait();
    
    
    
                    List<Task<string>> tasklist = new List<Task<string>>();
                    tasklist.Add(task1);
                    tasklist.Add(task2);
                    tasklist.Add(task3);
                    tasklist.Add(task4);
                    tasklist.Add(task5);
                    tasklist.Add(task6);
    
                    string[] storearray = await Task.WhenAll(tasklist);
    
                    PrintRow(DateTime.Now.ToString(), storearray[0], storearray[1], storearray[2], storearray[3], storearray[4], storearray[5]);
                    testlogger.extractitout(DateTime.Now + "," + string.Join(", ", storearray));
                }
                catch(Exception ex)
                {
                    testlogger.Log(ex.ToString());
                }
               
            }
    
            public static async Task<string> readChannel1()
            {
              
                    string result1 = " ";
                    //string s = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss fff", CultureInfo.InvariantCulture);
                    newsd.ReadFromChannel(channel1, result1);
                    //result1 = newsd.IML_LastDataString;
                    result1 = await Task.FromResult(newsd.IML_LastDataString);
                    return "Result 1 " + result1;
              
                
            }
    
            public static async Task<string> readChannel2()
            {
              
                    string result2 = " ";
                    //string s = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss fff", CultureInfo.InvariantCulture);
                    newsd.ReadFromChannel(channel2, result2);
                    result2 = await Task.FromResult(newsd.IML_LastDataString);
                    return "Result 2 " + result2;
               
    
            }
    
            public static async Task<string> readChannel3()
            {
               
                    string result3 = " ";
                    //string s = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss fff", CultureInfo.InvariantCulture);
                    newsd.ReadFromChannel(channel3, result3);
                    result3 = await Task.FromResult(newsd.IML_LastDataString);
    
                    return "Result 3 " + result3;
                
    
            }
    
            public static async Task<string> readChannel4()
            {
               
                    string result4 = " ";
                //string s = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss fff", CultureInfo.InvariantCulture);
                newsd.ReadFromChannel(channel4, result4);
                result4 = await Task.FromResult(newsd.IML_LastDataString);
    
                return "Result 4 " + result4;
               
            }
    
            public static async Task<string> readChannel5()
            {
                string result5 = " ";
                //string s = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss fff", CultureInfo.InvariantCulture);
                newsd.ReadFromChannel(channel5, result5);
                result5 = await Task.FromResult(newsd.IML_LastDataString);
    
                return "Result 5 " + result5;
            }
    
            public static async Task<string> readChannel6()
            {
                string result6 = " ";
                //string s = DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss fff", CultureInfo.InvariantCulture);
                newsd.ReadFromChannel(channel6, result6);
                result6 = await Task.FromResult(newsd.IML_LastDataString);
    
                return "Result 6 " + result6;
            }
    
    
        }
    }
    

    I was not using the Task.FromResult earlier, however I checked through the net and I am able to use it. The thing is I need all the readChannel functions to read the value at the same time. It is working now, but I would like to know what issues can I expect and how can I further improve it. I was reading and found some stuff on cache issues. Am I using the methods properly ?

    Earlier without the Task.FromResult, the values returned from the  

    (newsd.IML_LastDataString)

    was jumping from one channel to another. 

    Please advice.

     

    Monday, December 30, 2019 7:21 AM

Answers

  • Hello,

    Perhaps using WaitAll might be acceptable? Here is a very simple example with cancellation and progress.


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    • Marked as answer by cally_kalpana Tuesday, December 31, 2019 2:29 AM
    Monday, December 30, 2019 10:42 AM
    Moderator
  • " I need all the readChannel functions to read the value at the same time"

    This is not really possible even in the real world. If you have 6 threads trying to run at the same time but only 1 CPU then only 1 runs. Without injecting lots of sync blocks (which defeats the purpose of testing) to force the threads to run lock step there simply isn't any way to guarantee this type of behavior. 

    If you simply want to have all the tasks run at the same time (not necessarily together) and await the response then as Karen mentioned `WaitAll` will work. However the tasks will still run when they want to, not when you ask. You're just blocking until they all complete. 


    Michael Taylor http://www.michaeltaylorp3.net

    • Marked as answer by cally_kalpana Tuesday, December 31, 2019 2:29 AM
    Monday, December 30, 2019 3:13 PM
    Moderator
  • You say "it is working now", but because you call Wait on each task before starting the next one, you are actually running these one at a time, not in parallel.  Perhaps I'm missing some nuance here, but I believe you can simply remove the calls to ".Wait", and your code would do exactly what you want.  In fact, I don't think you need those "Task" variables at all.  You can just do this:

                    List<Task<string>> tasklist = new List<Task<string>>();
                    tasklist.Add(readChannel1());
                    tasklist.Add(readChannel2());
                    tasklist.Add(readChannel3());
                    tasklist.Add(readChannel4());
                    tasklist.Add(readChannel5());
                    tasklist.Add(readChannel6());
    


    Tim Roberts | Driver MVP Emeritus | Providenza &amp; Boekelheide, Inc.

    • Marked as answer by cally_kalpana Tuesday, December 31, 2019 2:29 AM
    Monday, December 30, 2019 8:15 PM

All replies

  • Hello,

    Perhaps using WaitAll might be acceptable? Here is a very simple example with cancellation and progress.


    Please remember to mark the replies as answers if they help and unmarked them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.

    NuGet BaseConnectionLibrary for database connections.

    StackOverFlow
    profile for Karen Payne on Stack Exchange

    • Marked as answer by cally_kalpana Tuesday, December 31, 2019 2:29 AM
    Monday, December 30, 2019 10:42 AM
    Moderator
  • " I need all the readChannel functions to read the value at the same time"

    This is not really possible even in the real world. If you have 6 threads trying to run at the same time but only 1 CPU then only 1 runs. Without injecting lots of sync blocks (which defeats the purpose of testing) to force the threads to run lock step there simply isn't any way to guarantee this type of behavior. 

    If you simply want to have all the tasks run at the same time (not necessarily together) and await the response then as Karen mentioned `WaitAll` will work. However the tasks will still run when they want to, not when you ask. You're just blocking until they all complete. 


    Michael Taylor http://www.michaeltaylorp3.net

    • Marked as answer by cally_kalpana Tuesday, December 31, 2019 2:29 AM
    Monday, December 30, 2019 3:13 PM
    Moderator
  • You say "it is working now", but because you call Wait on each task before starting the next one, you are actually running these one at a time, not in parallel.  Perhaps I'm missing some nuance here, but I believe you can simply remove the calls to ".Wait", and your code would do exactly what you want.  In fact, I don't think you need those "Task" variables at all.  You can just do this:

                    List<Task<string>> tasklist = new List<Task<string>>();
                    tasklist.Add(readChannel1());
                    tasklist.Add(readChannel2());
                    tasklist.Add(readChannel3());
                    tasklist.Add(readChannel4());
                    tasklist.Add(readChannel5());
                    tasklist.Add(readChannel6());
    


    Tim Roberts | Driver MVP Emeritus | Providenza &amp; Boekelheide, Inc.

    • Marked as answer by cally_kalpana Tuesday, December 31, 2019 2:29 AM
    Monday, December 30, 2019 8:15 PM
  • HI Michael

    Thank you for the advice. Really appreciate it.

    Tuesday, December 31, 2019 2:29 AM
  • Hi Tim

    Noted, will make the changes. 

    Tuesday, December 31, 2019 2:29 AM