-1

I am processing a list of textfiles in C#. Because of the performance, I use the Parallel.ForEach for this. I need to write to the richTextBox1 on my form, which file is being processed.

Since I was not able to access the form from different threads from the Parallel.ForEach, I created the WriteToBox method using Invoke.

public partial class Form2 : Form
{
    private static Form2 frmReference;
    private delegate void SafeCallDelegate(string text)
    public Form2()
    {
        InitializeComponent();
        frmReference = this;
    }
    public Dictionary<string, HashSet<string>> FindStrings(List<string> rccFiles)
    {
        Dictionary<string, HashSet<string>> sensitiveData = new Dictionary<string, HashSet<string>>();

        Parallel.ForEach(rccFiles, rccFile =>
        {
            //write which file is beeing processed
            WriteToBox("Searching in: " + rccFile);

           //some code
        });

        return sensitiveData;
    }

    public void WriteToBox(string text)
    {
        if (frmReference.richTextBox1.InvokeRequired)
        {
            var d = new SafeCallDelegate(WriteToBox);
            Invoke(d, new object[] { text });
        }
        else
        {
            frmReference.richTextBox1.AppendText("\r\n" + text);
            frmReference.richTextBox1.Update();
            frmReference.richTextBox1.ScrollToCaret();
        }
    }
}

When I run the program, it will only write the first processed file and the form freezes (deadlock?). Do you have an idea how to write to a textbox from a parallel loop? Thanks for any advice! Regards, Martin

xtmotoman
  • 9
  • 3

1 Answers1

3

Parallel.ForEach (running on UI thread) is waiting to all tasks to finish and so is the WriteToBox, because it wants to Invoke. These threads then get into deadlock. Easiest way to fix it is to replace Invoke to BeginInvoke.

Anothey way is to wrap Parallel.ForEach code into separate thread (non UI), since there is no need to this code to run on UI.

Task.Run(Parallel.ForEach(rccFiles, rccFile =>
{
    //write which file is beeing processed
    WriteToBox("Searching in: " + rccFile);

    //some code
}));
Tomas Chabada
  • 2,869
  • 1
  • 17
  • 18