Why can't we update the user interface from the workflow? same as other variables / object

Feel like asking a stupid question, but I want to know the answer. I do not need any code to update the user interface from the workflow. I know how to update user interface from worker / thread pool.

I want to know why we get this error "Incorrect cross-flow operation: Control", accessed from a stream other than the stream in which it was created. "when does any workflow try to update the user interface controls? and why does this error not occur when the workflow access object created by the Main thread and there is no interaction with the user interface?

See example below.

public partial class Form1 : Form
{
    private void Form1_Load(object sender, EventArgs e)
    {
    }

    TextBox textbox2 = null;
    List<int> collection = new List<int>();
    public Form1()
    {
        InitializeComponent();
        textbox2 = new TextBox();
    }
    public void UpdateTextBox()
    {
        collection.Add(Thread.CurrentThread.ManagedThreadId);
        textbox2.Text = "hi, ThreadId: " + Thread.CurrentThread.ManagedThreadId.ToString();
        panel1.Controls.Add(textbox2);//If remove this line... will work with worker thread.
    }
    private void btnMainThread_Click(object sender, EventArgs e)
    {
        UpdateTextBox();
    }
    private void btnWorkerThread_Click(object sender, EventArgs e)
    {
        Thread t1 = new Thread(UpdateTextBox);
        t1.Start();//Will get error. why?
    }
}

​​ "collection".?

+4
4

- - ( ) - , Control class Handle, , , , ( ).

Handle . InvokeRequired, .

.net Framework , . , , , Win32 API , - concurrency .

Handle , Win32 API, ( 'this' WIN32 API), -.

, ( ), ( ), "" . , .

InvokeRequired, , SafeNativeMethods.GetWindowThreadProcessId(), true, . , - getter Handle. , , , , .

+4

" " ( /), , , - . , , / - , , . (, , ..), ( , ).

Using " this.invoke(new Action(() => { UpdateText(); }));" is what you are looking for in your case. This can be called inline from the child stream without the occurrence of a cross-thread error, you just want to make sure that you are not deleting the shape, not positioning, etc. You can include several methods in the {} call.

Your concrete example

T1 Thread = new Thread(UpdateText);
T1.Start();

function UpdateText()
{
    this.invoke(new action(() =>{ textbox1.Text = "Some Text"; });
}

Useful example

Download Form

public partial class WaitWindow : Form
{

    public WaitWindow()
    {
        InitializeComponent();
    }

    internal void UpdateMessage(string Message)
    {
        lblMessage.Text = Message;
    }

}

Dialog Class

public class Dialog
{
    private static WaitForm WaitBox;

    public static void UpdateMessage(string Message)
    {
        if (WaitBox != null && WaitBox.IsHandleCreated && !WaitBox.IsDisposed && !WaitBox.IsDisposing)
        {
            WaitBox.Invoke(new Action(() =>{ WaitBox.UpdateMessage(Message); });
        }
    }
}
+1
source

you can use this to update any control from other threads

public void AppendTextBox(string value)
    {
        if (InvokeRequired)
        {
            this.Invoke(new Action<string>(AppendTextBox), new object[] {value});
            return;
        }
        textBox1.Text += value;
    }
0
source

Source: https://habr.com/ru/post/1678979/


All Articles