I run Player (), it runs prg1 in a new thread, and prg1 runs test (). Everything works without errors, НО на экране ничего не происходит ! А без нового потока - всё работает правильно НО на экране ничего не происходит ! А без нового потока - всё работает правильно

  Class Cls Public Shared Sub Player() Threading.ThreadPool.QueueUserWorkItem(AddressOf prg1) End Sub Private Shared Sub prg1() test() End Sub Public Shared Sub test() Form1.PB.Top = 100 Form1.PB.Left = 100 Form1.PB.Visible = True End Sub End Class 


    1 answer 1

    • First, what do you really want to do?

    I am sure that the idea to change the PictureBox1.Visible property from another thread did not come from a good life :)

    • Further, apparently, you do not really understand the concept of delegates in .NET and Invoke / BeginInvoke .

    ThreadStart is a delegate, and in itself it has nothing to do with working on another thread.

    • Further you hoped that the code you wrote will do what you want.
    • Unfortunately, the code you wrote is practically (with the exception of some subtleties related to the work of Invoke ) equivalent to simply calling test() from the same thread.

    • This is because Invoke performs the operation in the same thread where the control is created, that is, in your case, just in the UI thread.

    • The error returned is due to the fact that, in fact, the Form1 : Control object at the time of calling test() has not yet been created at the WinAPI level or, on the contrary, no longer exists, because in this case, the Invoke / BeginInvoke does not make sense for it.

    • In confirmation of the previous statement, consider the following snippet :

        var form1 = new Form1(); // Если убрать 'form1.Show()', то это приведет к // ошибке, аналогичной той, которая указана у вас в вопросе. form1.Show(); form1.Invoke(new Action(() => { form1.Text = "Some new text"; })); 
    • And now - the most delicious. The Invoke / BeginInvoke , generally speaking, is intended for a situation diametrically opposite to the one you described in your question.

    • That is, its main task is to enable the user to update the state of the UI from another thread.

    • Roughly speaking, you may have some Worker Thread, that needs to update the UI at some point in time (this is an anti-pattern, but it will come down as an example).

    • In this case, from the code that works in Worker Thread you can refer to the control created in another thread and perform any actions using Invoke / BeginInvoke. An attempt to perform actions to update the UI directly from another thread will fail, since this is not provided for in WinAPI and, as a result, in Windows.Forms .

    • @ Kotik_hochet_kushat I run Form1.Invoke (New Threading.ThreadStart (AddressOf test)) from the procedure called in the new thread - dizar47 4:56 pm
    • @ dizar47 In this case, it was more accurate to reflect this in the question, as well as see the middle of the answer. - Costantino Rupert