0

I want to change textbox's text on Form2 with thread on Form1.

Normally when I click button on Form1 it changes textbox's text on Form2, but if I execute same code but on separate thread, still on Form1, it doesn't change textbox's text.

I've tried adding messagebox, which showed up successfully, so I think it just skips textbox line.

I've also added Control.CheckForIllegalCrossThreadCalls = False on both forms' load, but it's still the same.

There are no errors

Private Sub myThread()
    Form2.TextBox1.Text = "foo" 'text is not changing
    MsgBox("123") 'messagebox is showing up
End Sub
Stefan Đorđević
  • 565
  • 1
  • 4
  • 22
  • You cannot use any thread other than the UI thread for create, reading or updating any UI element - this includes forms. – Enigmativity Jun 23 '18 at 12:21
  • I've found out from some other answers that this can be performed using "delegate", I think. Any idea how to use it into this code? I guess it's simple but I've never worked with it before. – Stefan Đorđević Jun 23 '18 at 12:37
  • A `delegate` is just a way of holding a reference to a method in a variable. It's how you use the `delegate` that matters. You're probably referring to `.Invoke(delegate)`. Would that be right? – Enigmativity Jun 23 '18 at 12:44
  • 2
    `Control.CheckForIllegalCrossThreadCalls = False`, never do that... – Trevor Jun 23 '18 at 12:45
  • 2
    @Codexer - Yes, never do that. It's like telling everyone not to tell you that running with scissors is dangerous and then you go running with scissors - it's still dangerous, just no-one is warning you any more. – Enigmativity Jun 23 '18 at 12:48
  • 1
    Standard vb.net trap, `Form2` does *not* reference the form object that you are looking at. Since the code runs on a worker thread it creates another object of the Form2 class. You can't see it because its Show() method was never called. You must use a proper object reference, not the type name. And you can't directly assign the Text property, that is illegal from a worker thread. Fix that latter problem first, the object reference then takes care of itself. – Hans Passant Jun 23 '18 at 12:51
  • I know people are saying that it shouldn't be used in "more complex" applications, but so far I've never had any problems with it. @Enigmativity yes, that what I was thinking on, I'm currently researching it a bit. – Stefan Đorđević Jun 23 '18 at 12:51
  • Another option, databind your data objects to the UI controls and then no need to access the UI thread... – Trevor Jun 23 '18 at 12:55
  • [How to: Make Thread-Safe Calls to Windows Forms Controls](https://learn.microsoft.com/en-us/dotnet/framework/winforms/controls/how-to-make-thread-safe-calls-to-windows-forms-controls) – TnTinMn Jun 23 '18 at 13:40
  • _"I know people are saying that it shouldn't be used in 'more complex' applications"_ - You shouldn't be changing `Control.CheckForIllegalCrossThreadCalls` in **ANY** application! Nothing good comes from setting it to false! See this: https://stackoverflow.com/a/13345622 – Visual Vincent Jun 23 '18 at 18:09
  • 1
    As for your issue, [**this**](https://stackoverflow.com/a/45948766/3740093) should shed some light on why it isn't working at all (in addition to Hans's comment), and [**this**](https://stackoverflow.com/a/45571728/3740093) explains how you can access the UI **properly** (start reading from _**Accessing the UI thread**_ and down). Pay attention to the _**Making it simpler**_ part, because properly accessing the UI from a thread _does not_ have to be hard at all. – Visual Vincent Jun 23 '18 at 18:18
  • With my _**Making it simpler**_ part all you need to do is (assuming you're using Visual Basic 2010 or later): `Me.InvokeIfRequired(Sub() Form2.TextBox1.Text = "foo")` and your code will be thread-safe, and work without a problem. – Visual Vincent Jun 23 '18 at 18:25

0 Answers0