Using of Thread within a constructor?

105 views Asked by At

I am a newbie and trying to learn the right way.

Is it acceptable to use a Thread within a constructor to avoid gui(Form) to freeze when an object is created? I will reuse this class often.

class Cmd
{
    protected static string parameters;
    protected HashSet<string> list_result;

    public Cmd( string parameters)
    {
        Thread Thread1 = new Thread(new ThreadStart(Process1));
        Thread1.Start();
        Thread1.Join();
    }

     private void Process1()
    {
        ProcessStartInfo processStartInfo = new ProcessStartInfo("cmd", "/c " + parameters);
        processStartInfo.RedirectStandardOutput = true;
        processStartInfo.RedirectStandardError = true;
        processStartInfo.CreateNoWindow = true;
        processStartInfo.UseShellExecute = false;

        Process process = Process.Start(processStartInfo);

        list_result = new HashSet<string>();
        while (!process.StandardOutput.EndOfStream)
        {
            string line = process.StandardOutput.ReadLine();
            list_result.Add(line);
        }
    }
2

There are 2 answers

6
Denis  Yarkovoy On

If you would like to avoid freeze in your UI when doing a time-consuming task, you should add BackgroundWorker to your form and run your task in its event handler

You can find the example here: https://msdn.microsoft.com/en-us/library/cc221403%28v=vs.95%29.aspx

You should also consider using newer async/await logic which is usually better than BackgroundWorker, as Panagiotis Kanavos mentioned in his answer

0
Panagiotis Kanavos On

You don't even need a thread for this. You can use the StreamReader's asynchronous methods to read the input lines asynchronously:

    private async void button1_Click(object sender, EventArgs e)
    {
        var lines=await Process1(@"dir g:\ /s");
        var result= String.Join("|", lines);
        this.textBox1.Text = result;
    }

    private async Task<HashSet<String>>   Process1(string parameters)
    {
        var list_result = new HashSet<string>();
        ProcessStartInfo processStartInfo = new ProcessStartInfo("cmd", "/c " + parameters);
        processStartInfo.RedirectStandardOutput = true;
        processStartInfo.RedirectStandardError = true;
        processStartInfo.CreateNoWindow = true;
        processStartInfo.UseShellExecute = false;

        Process process = Process.Start(processStartInfo);


        while (!process.StandardOutput.EndOfStream)
        {
            string line = await process.StandardOutput.ReadLineAsync();
            list_result.Add(line);
        }
        return list_result;
    }

The advantage is that you don't waste a thread, you don't need any synchronization code or static fields to pass the parameters and read the results.