Keeping thread safe user interface access devices in a separate class in C #

In my multi-threaded applications, I need to access cross-threads in user interface elements, and I use safe-flow methods to do this. I use this many times in many of my projects and save them in a form file so that the file looks ugly. So I want to create a seprate class where I can put all this and call them when necessary, but I am having problems with it. For instace to change the text element of the control I use the following

delegate void SetTextCallback(string text, Control ctrl);

public void SetText(string text, Control ctrl)
    {
        if (ctrl.InvokeRequired)
        {
            SetTextCallback d = new SetTextCallback(SetText);
            this.Invoke(d, new object[] { text, ctrl });
        }
        else
        {
            if (ctrl.GetType() == typeof(Label))
            {
                ctrl.Text = text;
            }
            else
            {
                ctrl.Text += Environment.NewLine + text;
            }
        }
    }

and call this function as

SetText("some text",label1);

This works fine if it is in a form class, if I put it in another class, I get an error in the line

this.Invoke(d, new object[] { text, ctrl });

- , .

, , , , , , , . -

public void ChangePropert(Control ctrl,Property prop,Value val)
+3
3

, , . , , , .

- , , . , .

, . .

:

public partial class Form1 : Form
{
    private SynchronizationContext _synchronizationContext;

    public Form1()
    {
        InitializeComponent();
        //Client must be careful to create sync context somehwere they are sure to be on main thread
        _synchronizationContext = AsyncOperationManager.SynchronizationContext;
    }

    //Callback method implementation - must be of this form
    public void ReceiveThreadData(object threadData)
    {
        // This callback now exeutes on the main thread.
        // Can use directly in UI without error
        this.listBoxMain.Items.Add((string)threadData);
    }

    private void DoSomeThreadWork()
    {
        // Thread needs callback and sync context so it must be wrapped in a class.
        SendOrPostCallback callback = new SendOrPostCallback(ReceiveThreadData);
        SomeThreadTask task = new SomeThreadTask(_synchronizationContext, callback);
        Thread thread = new Thread(task.ExecuteThreadTask);
        thread.Start();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        DoSomeThreadWork();
    }

}

:

/// SomeThreadTask defines the work a thread needs to do and also provides any data ///required along with callback pointers etc.
/// Populate a new SomeThreadTask instance with a synch context and callnbackl along with ///any data the thread needs
/// then start the thread to execute the task.
/// </summary>
public class SomeThreadTask
{

    private string _taskId;
    private SendOrPostCallback _completedCallback;
    private SynchronizationContext _synchronizationContext;

    /// <summary>
    /// Get instance of a delegate used to notify the main thread when done.
    /// </summary>
    internal SendOrPostCallback CompletedCallback
    {
        get { return _completedCallback; }
    }

    /// <summary>
    /// Get SynchronizationContext for main thread.
    /// </summary>
    internal SynchronizationContext SynchronizationContext
    {
        get { return _synchronizationContext; }
    }

    /// <summary>
    /// Thread entry point function.
    /// </summary>
    public void ExecuteThreadTask()
    {

        //Just sleep instead of doing any real work
        Thread.Sleep(5000);

        string message = "This is some spoof data from thread work.";

        // Execute callback on synch context to tell main thread this task is done.
        SynchronizationContext.Post(CompletedCallback, (object)message);


    }

    public SomeThreadTask(SynchronizationContext synchronizationContext, SendOrPostCallback callback)
    {
        _synchronizationContext = synchronizationContext;
        _completedCallback = callback;
    }

}

.

+2

. , , .

, : label1.SetText("some text"); instad SetText("some text", label1);

, , . .

, . , Type.GetProperty(). PropertyInfo, :

var textProperty = label1.GetType().GetProperty("Text");
textProperty.SetValue(label1, "some text", null);
0

, , ?
, , CheckForIllegalCrossThreadCalls false form, , .

CheckForIllegalCrossThreadCalls - MSDN

-1

All Articles