Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problem with delegate Syntax in C#

I built a Testbox to learn something about threading in windows form applications. Silverlight and Java are providing the Dispatcher, which really helps when updating GUI Elements.

Code Samples: Declaration Class Delegate

public delegate void d_SingleString(string newText);

Create Thread

        _thread_active = true;
        Thread myThread = new Thread(delegate() { BackGroundThread(); });
        myThread.Start();

Thread Function

    private void BackGroundThread()
    {
        while (_thread_active)
        {
            MyCounter++;
            UpdateTestBox(MyCounter.ToString());
            Thread.Sleep(1000);
        }
    }

Delegating TextBox Updates

    public void UpdateTestBox(string newText)
    {
        if (InvokeRequired)
        {
            BeginInvoke(new d_SingleString(UpdateTestBox), new object[] { newText });
            return;
        }
        tb_output.Text = newText;
    }

Is there a way to declare the Declaration of the Delate IN the BeginInvoke Method?!

something like

BeginInvoke(*DELEGATE DECLARATION HERE*, new object[] { newText });

Many thanks, rAyt

like image 734
Henrik P. Hessel Avatar asked May 25 '09 09:05

Henrik P. Hessel


2 Answers

In many cases like this, the simplest approach is to use a "captured variable" to pass state between the threads; this means you can keep the logic localised:

public void UpdateTestBox(string newText)
{
    BeginInvoke((MethodInvoker) delegate {
        tb_output.Text = newText;
    });        
}

The above is particularly useful if we expect it to be called on the worker thread (so little point checking InvokeRequired) - note that this is safe from either the UI or worker thread, and allows us to pass as much or as little state between the threads.

like image 161
Marc Gravell Avatar answered Oct 31 '22 22:10

Marc Gravell


For simple delegates like this you can use the Action<T> delegate (link to msdn) from the framework.

public void UpdateTestBox(string newText)
{
    if (InvokeRequired)
    {
        BeginInvoke(new Action<string>(UpdateTestBox), new object[] { newText });
        return;
    }
    tb_output.Text = newText;
}

That way you do not need to maintain your own delegate declarations.

like image 41
Fredrik Mörk Avatar answered Oct 31 '22 20:10

Fredrik Mörk