johnny 5
johnny 5

Reputation: 20997

Thread Safe, prevent variables from updating

I have a delegate that is being executed in a threadpool. A count gets passed in correctly as a variable, however, when the program goes to return the output, The initial value passed in is now the updated version. How can I modify ths so the variable stays the correct value?

    private void SetControlText(TextBox TB, string txt)
    {
        if (TB.InvokeRequired)
        {
            Invoke((MethodInvoker)delegate
            {
                TB.AppendText(txt + "\n");
                TB.Update();
            });
            return;
        }

        TB.Text = txt;
    }

    private void DoWork(OCAdapter.OCAdapter Adapter, OutputForm output, int c, object ThreadContext = null)
    {
        int count = c;
        //output.AppendToOutput("Initializing Adapter: " + count + " Test\n");
        SetControlText(output.OutputBx, "Initializing Adapter: " + count + " Test\n");
        try
        {
            var Test = Adapter.GetBookmarks();
            if (Test != null)
                //output.AppendToOutput("Adapter: " + count + " is valid\n");
                SetControlText(output.OutputBx, "Adapter: " + count + " is valid\n");
        }
        catch (Exception ex)
        {
            //output.AppendToOutput("Exception occured on adapter: " + count + " Exception: " + ex.Message);
            SetControlText(output.OutputBx, "Exception occured on adapter: " + count + " Exception: " + ex.Message);
        }
    }

Upvotes: 1

Views: 122

Answers (2)

johnny 5
johnny 5

Reputation: 20997

Hey I actually found out the answer, the threads were using shared memory so they were accessing the variable after it was incremented.

The way I fixed this is by passing in a temporary variable with the count.

Upvotes: 1

Idle_Mind
Idle_Mind

Reputation: 39122

Your SetControlText() isn't quite right. It's doing BOTH an Invoke() and also setting the Text anyways, from the wrong thread, directly below that; every time.

Try something like this instead and see if the problem goes away:

    private delegate void SetControlTextDelegate(TextBox TB, string txt);
    private void SetControlText(TextBox TB, string txt)
    {
        if (TB.InvokeRequired)
        {
            TB.Invoke(new SetControlTextDelegate(SetControlText), new object[] { TB, txt });
        }
        else
        {
            TB.AppendText(txt + Environment.NewLine);
        }
    }

Upvotes: 0

Related Questions