0

Currently I have a button that calls a function and has a processing time of 10-20 secs. Is it possible to have some text like "please wait..." rather than the application getting hang.

Here is button where I call my function:

private void btnExec_Click(object sender, EventArgs e)
        {
            LongProcess();
        }

And this is the function that executes too long:

 public void LongProcess()
        {
            DataTable table = new DataTable();

            table.Columns.Add("DateTime", typeof(string));
            table.Columns.Add("Mass1", typeof(string));
            table.Columns.Add("Mass2", typeof(string));
            table.Columns.Add("Mass3", typeof(string));               

            Console.WriteLine(startDate.Value);
            Console.WriteLine(endDate.Value);

            decimal v = decimal.Parse("1.6345e-008", NumberStyles.Float);
            var pattern = @"^""\d+/\d+/\d+ \d+:\d+:\d+ (AM|PM)""\s+-?\d+\s+\d+.?\d+e-\d+";
            var regex = new Regex(pattern, RegexOptions.Compiled);

            string[] filePaths = Directory.GetFiles(@"C:\\test\\", "*.txt");

            var results = new List<string>();

            foreach (var file in filePaths)
            {
                var lines = File.ReadLines(file).Where(x => regex.IsMatch(x));
                results.AddRange(lines);
            }

            foreach (var result in results)
            {
                string[] words = (result.ToString()).Split(' ');
                string date = words[0].Substring(1) + " " + words[1];

                DateTime oDate = DateTime.Parse(date);

                if (oDate >= startDate.Value && oDate <= endDate.Value)
                {
                    string[] words2 = (words[2].ToString()).Split('\t');
                    string m1 = words2[2];
                    string m2 = words2[3];
                    string m3 = words2[4];                           
                    table.Rows.Add(new object[] { oDate.ToString(), m1, m2, m3});

            File.WriteAllText(@"C:\\test.csv", sb.ToString());
            Console.WriteLine("Done Parsing");
        }

Any suuggestion/comments TIA.

Syntax Rommel
  • 932
  • 2
  • 16
  • 40

1 Answers1

2

The simplest way to do this would be to offload the work to a new Thread/Task and use the Async Await Pattern

private async void btnExec_Click(object sender, EventArgs e)
{
    try
    {
       await Task.Run(() => LongProcess());
       // or
       await Task.Run(LongProcess);
    }
    catch (Exception exception)
    {
       // catch any exceptions, as this method will be unobserved 
       // Console.WriteLine(exception);
    }
}
  • You will probably want to catch any exceptions in your click event as it's an async void. Leaving exceptions unobserved like this can cause issues

  • If you were worried about thread-pool threads being used, you could use Task.Factory.StartNew with the TaskCreationOptions.LongRunning option

  • You might also want guard against multiple presses

  • Lastly, when offloading CPU bound work like this, you cannot update the UI in certain frameworks (like Winforms or WPF) without marshalling back to the UI Context. See this question for some related information on progress updates C# async/await Progress event on Task<> object

halfer
  • 19,824
  • 17
  • 99
  • 186
TheGeneral
  • 79,002
  • 9
  • 103
  • 141