none
Why BeginInvoke makes my UI dead? RRS feed

  • Question

  • Hello all——

    Any Control in the WinForm can have the important of BeginInvoke, it offers the asynchronized……But when I use BeginInvoke to execute a very complicated task, my UI becomes dead……Why?Doesn't work asychronizedly?

    Even if I call BeginInvoke in a thread, my UI still dead……:(

    So my questions are:

    1)What's BeginInvoke?Will it create a thread?

    2)What's Invoke?Since Invoke will execute the action sychronized?What's the MOST DIFFERENCE between calling the method and by referring Invoke?

    Plz answer one by one by quoting, many thanks!

    Wednesday, August 8, 2012 7:32 AM

Answers

  • Hello all——

    Any Control in the WinForm can have the important of BeginInvoke, it offers the asynchronized……But when I use BeginInvoke to execute a very complicated task, my UI becomes dead……Why?Doesn't work asychronizedly?

    Even if I call BeginInvoke in a thread, my UI still dead……:(

    So my questions are:

    1)What's BeginInvoke?Will it create a thread?

    2)What's Invoke?Since Invoke will execute the action sychronized?What's the MOST DIFFERENCE between calling the method and by referring Invoke?

    Plz answer one by one by quoting, many thanks!

    Hi Ignoredrei,

    Nice to see you again.

    Just one sentance: whatever you use beginInvoke or Invoke to execute your complex task, the UI always be frozen. Because it will be executed in UI thread.

    The biggest different between beginInvoke and Invoke is the beginInvoke doesn't block the calling thread, but Invoke will wait for the called method return.

    I hope this will be clear.

    Best regards,


    Mike Feng
    MSDN Community Support | Feedback to us
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Friday, August 10, 2012 9:56 AM
    Moderator

All replies

  • Wednesday, August 8, 2012 8:30 AM
  • Still cannot understand……Would u mind simply answering me?

    Thx

    Wednesday, August 8, 2012 8:40 AM
  • BeginInvoke will execute on a different thread whereas Invoke executes on the same thread.

    Your UI is getting freezed because possibly you are accessing a UI element within a method that is called using BeginInvoke. So, check for such thing in your code.


    Please mark this post as answer if it solved your problem. Happy Programming!

    Wednesday, August 8, 2012 9:19 AM
  • Invoke blocks both the calling and executing (UI) thread.  It calls a method and waits until it completes.  BeginInvoke blocks only the executing  (UI) thread.  It calls a method and returns.  Invoke calls SendMessage and BeginInvoke calls PostMessage.

    • Edited by JohnWein Wednesday, August 8, 2012 10:07 AM
    Wednesday, August 8, 2012 9:55 AM
  • BeginInvoke will execute on a different thread whereas Invoke executes on the same thread.

    Your UI is getting freezed because possibly you are accessing a UI element within a method that is called using BeginInvoke. So, check for such thing in your code.


    Please mark this post as answer if it solved your problem. Happy Programming!

    Hi,

    Do u mean if I use Control.BeginInvoke to execute a long task……My UI is still dead?if so, why BeginInvoke?

    Thursday, August 9, 2012 2:26 AM
  • Invoke blocks both the calling and executing (UI) thread.  It calls a method and waits until it completes.  BeginInvoke blocks only the executing  (UI) thread.  It calls a method and returns.  Invoke calls SendMessage and BeginInvoke calls PostMessage.

    What do u mean——

    BeginInvoke blocks only the executing  (UI) thread.

    Thursday, August 9, 2012 2:26 AM
  • Hi all

    Since "BeginInvoke" will start another thread, this shouldn't make my UI dead……but in fact when I use Control.BeginInvoke, my UI really dead! Why?

    Another question is if I use a delegate's BeginInvoke, my UI not dead and everything goes well with me, but if I run the app in Debug mode, it throws an exception to tell me that You cannot access a control from a thread that doesn't create it

    Why????

    I really don't know the MOST DIFFERENCE between Control.BeginInvoke and SomeDeletegate.BeginInvoke????????

    Thursday, August 9, 2012 2:31 AM
  • "Since "BeginInvoke" will start another thread"

    Where did you get this idea?  Are you reading the responses in this thread to your question.  You need to study the Windows messaging system.


    • Edited by JohnWein Thursday, August 9, 2012 4:25 AM
    Thursday, August 9, 2012 4:24 AM
  • Hello all——

    Any Control in the WinForm can have the important of BeginInvoke, it offers the asynchronized……But when I use BeginInvoke to execute a very complicated task, my UI becomes dead……Why?Doesn't work asychronizedly?

    Even if I call BeginInvoke in a thread, my UI still dead……:(

    So my questions are:

    1)What's BeginInvoke?Will it create a thread?

    2)What's Invoke?Since Invoke will execute the action sychronized?What's the MOST DIFFERENCE between calling the method and by referring Invoke?

    Plz answer one by one by quoting, many thanks!

    Hi Ignoredrei,

    Nice to see you again.

    Just one sentance: whatever you use beginInvoke or Invoke to execute your complex task, the UI always be frozen. Because it will be executed in UI thread.

    The biggest different between beginInvoke and Invoke is the beginInvoke doesn't block the calling thread, but Invoke will wait for the called method return.

    I hope this will be clear.

    Best regards,


    Mike Feng
    MSDN Community Support | Feedback to us
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Friday, August 10, 2012 9:56 AM
    Moderator
  • Many thanks Mike!

    >>The biggest different between beginInvoke and Invoke is the beginInvoke doesn't block the calling thread, but Invoke will wait for the called method return.

    What do u mean "doesn't block the calling thread"?

    Can u offer me an example to prove the MOST DIFFERENCE?

    Thx again

    Saturday, August 11, 2012 2:37 AM
  • Ignoredrei

    Read at least the chapters "Delegates" to "Control BeginInvoke/Invoke" of my SerialPort tutorial. This should explain BeginInvoke and Invoke. Just forget that it is a SerialPort tutorial and that all examples are in VB. It works the same way in C#.

    Note what Mike Feng writes! The routine or function you call by means of BeginInvoke or Invoke runs on the UI thread. This means that while this routine or function is executing, the UI thread is dead for other purposes, so look for the block in the routine or function you call! Probably this routine or function makes a deadlock by waiting for some input from another routine or function, which also runs on the UI thread.

     


    Everything should be made as simple as possible, but not simpler. Any fool can write code that a computer can understand. Good programmers write code that humans understand.

    • Proposed as answer by Ellen Ramcke Monday, August 13, 2012 7:55 AM
    Saturday, August 11, 2012 1:45 PM
  • So do u mean——

    BeginInvoke:Move the task later and do execution of the event where BeginInvoke is called, and then call BeginInvoke.

    Invoke:Do step by step

    ???

    Sunday, August 12, 2012 8:23 AM
  • No.

    Read the tutorial. If you don't understand the specified chapters, read the tutorial right from the beginning and don't step to a new chapter before you really understand the present one. It may take you a week, but you will learn a lot, and I have spend at least a month writing it, so I don't fell sorry for you :-)

    I wrote the tutorial because I was tired of answering the same questions again and again. Now you ask some questions, which shows that you have either not bothered to read it or you don't understand it. If the latter is the case, just tell me what you don't understand in which chapter, but if the first is the case - you lazy guy :-)


    Everything should be made as simple as possible, but not simpler. Any fool can write code that a computer can understand. Good programmers write code that humans understand.

    Sunday, August 12, 2012 3:46 PM
  • Carsten Kanstrup

    First many thanks!

    After reading ur article, it seems that you mean BeginInvoke will delay the task in the method itself for a period time by sending it into message query until it's executed after the main event of UI thread is executed. But Invoke will be executed until it's finished, the main UI will still to continue.

    Am I right?

    • Edited by TimoYang Monday, August 13, 2012 1:24 AM
    Monday, August 13, 2012 1:24 AM
  • Carsten Kanstrup

    First many thanks!

    After reading ur article, it seems that you mean BeginInvoke will delay the task in the method itself for a period time by sending it into message query until it's executed after the main event of UI thread is executed. But Invoke will be executed until it's finished, the main UI will still to continue.

    Am I right?

    Hi Ignored,

    Yes, I agree.

    And here is the test code:

        Dim t1 As New Thread(AddressOf ForInvoke)
        Dim t2 As New Thread(AddressOf ForBeginInvoke)
        Private Delegate Sub HeavyWorkDelegate()
    
        Private Sub Button1_In_Click(sender As System.Object, e As System.EventArgs) Handles Button1_In.Click
            t1.Start()
        End Sub
    
        Private Sub ForInvoke()
            Me.Invoke(New HeavyWorkDelegate(AddressOf HeavyWorkInvoke))
            Console.WriteLine("Button1_In_Click!")
        End Sub
        Private Sub HeavyWorkInvoke()
            If Me.InvokeRequired Then
                Me.Invoke(New HeavyWorkDelegate(AddressOf HeavyWorkInvoke))
            Else
                Dim i As Integer = 0
                While i < Integer.MaxValue
                    i += 1
                End While
                Console.WriteLine("Work is done!")
            End If
        End Sub
        Private Sub HeavyWorkBeginInvoke()
            If Me.InvokeRequired Then
                Me.BeginInvoke(New HeavyWorkDelegate(AddressOf HeavyWorkBeginInvoke))
            Else
                Dim i As Integer = 0
                While i < Integer.MaxValue
                    i += 1
                End While
                Console.WriteLine("Work is done!")
            End If
        End Sub
    
        Private Sub Button2_Be_Click(sender As System.Object, e As System.EventArgs) Handles Button2_Be.Click
            t2.Start()
        End Sub
    
        Private Sub ForBeginInvoke()
            Me.BeginInvoke(New HeavyWorkDelegate(AddressOf HeavyWorkBeginInvoke))
            Console.WriteLine("Button2_Be_Click!")
        End Sub

    For test, please drag two buttons in a form.

    When you click button1_In, you will get this result:

    Work is done!
    Button1_In_Click! 

    When you click button2_Be, you will get this result:

    Button2_Be_Click!
    Work is done!

    When you click each of the two button, the UI will be block.

    @Carsten,

    Thank you for your contribution on this forum. Thank you very much.

    Best regards,


    Mike Feng
    MSDN Community Support | Feedback to us
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.


    Monday, August 13, 2012 2:45 AM
    Moderator
  • @ John Wein

    "Invoke calls SendMessage and BeginInvoke calls PostMessage."

    Sorry, but as far as I know, this is not true. It is correct that Invoke is equivalent to a SendMessage call, but to avoid that Invoke gets higher priority than BeginInvoke, they both use a PostMessage. In fact, control.Invoke and control.BeginInvoke calls the same method MarshaledInvoke, which calls UnsafeNativeMethods.PostMessage(....). The only difference is that BeginInvoke does not wait for the job to be done.

     

    @ Ignoredrei

    "After reading ur article, it seems that you mean BeginInvoke will delay the task in the method itself for a period time by sending it into message query until it's executed after the main event of UI thread is executed. But Invoke will be executed until it's finished, the main UI will still to continue."

    No. As you can see above in my comment to John (although you may not understand it), control.BeginInvoke and Control.Invoke do almost the same, and in most cases - probably also your, they both post the message to the message queue as explained in my totorial. The only difference is, that BeginInvoke returns as soon as the message has been posted, but Invoke does not return until the message has actually been processed on the UI thread.


    Everything should be made as simple as possible, but not simpler. Any fool can write code that a computer can understand. Good programmers write code that humans understand.

    Monday, August 13, 2012 7:09 PM
  •  Invoke calls SendMessage and BeginInvoke calls PostMessage.

    "Sorry, but as far as I know, this is not true. It is correct that Invoke is equivalent to a SendMessage call, but to avoid that Invoke gets higher priority than BeginInvoke, they both use a PostMessage. In fact, control.Invoke and control.BeginInvoke calls the same method MarshaledInvoke, which calls UnsafeNativeMethods.PostMessage(....). The only difference is that BeginInvoke does not wait for the job to be done."

    Do You really think the OP will understand a call to MarshaledInvoke better than SendMessage and PostMessage?  An Invoke call is fuly equivalent to a SendMessage call and BeginInvoke is fully equivalent to a PostMessage call.  The documentation of Send and Post message should be easier for most coders to understand than the documentation for MarshaledInvoke if it can be found.

    Monday, August 13, 2012 7:53 PM
  • @ John Wein

    "Do You really think the OP will understand a call to MarshaledInvoke better than SendMessage and PostMessage?"

    No, and I don't think that he will understand SendMessage and PostMessage either :-) As you can see in my post, this comment was addressed to you. If you cannot find any documentation for MarshaledInvoke, you can find a simplified listing in chapter "Control Invoke/BeginInvoke" of my SerialPort tutorial.


    Everything should be made as simple as possible, but not simpler. Any fool can write code that a computer can understand. Good programmers write code that humans understand.

    Monday, August 13, 2012 9:18 PM
  • @ John Wein

    "Do You really think the OP will understand a call to MarshaledInvoke better than SendMessage and PostMessage?"

    No, and I don't think that he will understand SendMessage and PostMessage either :-) As you can see in my post, this comment was addressed to you. If you cannot find any documentation for MarshaledInvoke, you can find a simplified listing in chapter "Control Invoke/BeginInvoke" of my SerialPort tutorial.


    Everything should be made as simple as possible, but not simpler. Any fool can write code that a computer can understand. Good programmers write code that humans understand.


    I understand that your primary objective is trafficking your web site.  I can find all the info I need for MarshaledInvoke, but I don't think the OP can as easily as he can for send and post message.
    Monday, August 13, 2012 9:29 PM
  • @ John Wein

    "I understand that your primary objective is trafficking your web site."

    Nonsense :-(

    I wrote the tutorial because I was tired of answering the same questions again and again and also wanted a place to collect my knowledge about SerialPort. I then put the tutorial on the web hotel of my company since I had no other place to put it.


    Everything should be made as simple as possible, but not simpler. Any fool can write code that a computer can understand. Good programmers write code that humans understand.

    Monday, August 13, 2012 9:47 PM
  • Can anyone at present summerize ur idea in one or a pharaghu of that problem?

    Thx again

    Tuesday, August 14, 2012 8:39 AM
  • Carsten Kanstrup

    First many thanks!

    After reading ur article, it seems that you mean BeginInvoke will delay the task in the method itself for a period time by sending it into message query until it's executed after the main event of UI thread is executed. But Invoke will be executed until it's finished, the main UI will still to continue.

    Am I right?

    Hi Ignored,

    Yes, I agree.

    And here is the test code:

        Dim t1 As New Thread(AddressOf ForInvoke)
        Dim t2 As New Thread(AddressOf ForBeginInvoke)
        Private Delegate Sub HeavyWorkDelegate()
    
        Private Sub Button1_In_Click(sender As System.Object, e As System.EventArgs) Handles Button1_In.Click
            t1.Start()
        End Sub
    
        Private Sub ForInvoke()
            Me.Invoke(New HeavyWorkDelegate(AddressOf HeavyWorkInvoke))
            Console.WriteLine("Button1_In_Click!")
        End Sub
        Private Sub HeavyWorkInvoke()
            If Me.InvokeRequired Then
                Me.Invoke(New HeavyWorkDelegate(AddressOf HeavyWorkInvoke))
            Else
                Dim i As Integer = 0
                While i < Integer.MaxValue
                    i += 1
                End While
                Console.WriteLine("Work is done!")
            End If
        End Sub
        Private Sub HeavyWorkBeginInvoke()
            If Me.InvokeRequired Then
                Me.BeginInvoke(New HeavyWorkDelegate(AddressOf HeavyWorkBeginInvoke))
            Else
                Dim i As Integer = 0
                While i < Integer.MaxValue
                    i += 1
                End While
                Console.WriteLine("Work is done!")
            End If
        End Sub
    
        Private Sub Button2_Be_Click(sender As System.Object, e As System.EventArgs) Handles Button2_Be.Click
            t2.Start()
        End Sub
    
        Private Sub ForBeginInvoke()
            Me.BeginInvoke(New HeavyWorkDelegate(AddressOf HeavyWorkBeginInvoke))
            Console.WriteLine("Button2_Be_Click!")
        End Sub

    For test, please drag two buttons in a form.

    When you click button1_In, you will get this result:

    Work is done!
    Button1_In_Click! 

    When you click button2_Be, you will get this result:

    Button2_Be_Click!
    Work is done!

    When you click each of the two button, the UI will be block.

    @Carsten,

    Thank you for your contribution on this forum. Thank you very much.

    Best regards,


    Mike Feng
    MSDN Community Support | Feedback to us
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.


    Mike, Thx

    But ur idea isn't the same as

    Carsten Kanstrup

    so who is right?!

    • Edited by TimoYang Tuesday, August 14, 2012 8:40 AM
    Tuesday, August 14, 2012 8:40 AM
  • Hi Ignoredrei,

    I have read Carsten's opinion, I don't think we are converse.

    Carsten said "BeginInvoke will delay the task in the method itself",  and he means the task itself, not the BeginInvoke method. So we are not conflict.

    Best regards,


    Mike Feng
    MSDN Community Support | Feedback to us
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Tuesday, August 14, 2012 9:51 AM
    Moderator
  • @ Mike Feng

    "Carsten said "BeginInvoke will delay the task in the method itself", ...."

    Sorry, but this is not my words. It is the words of Ignoredrei - see his post of monday 13th 1:24 AM.

    @ Ignoredrei:

    Since there are both delegate.BeginInvoke/Invoke and control.BeginInvoke/Invoke and they may do different things depending on from which task they are called, it can be quite confusing.

    Study the chapters again and also the part of the tutorial, which describes the multitasking. It is a very big subject, and there is no reason to repeat here what I have already written in the tutorial. If you don't understand it, just let me know, but it is quite obvious that there is something basic about multitasking and communication between tasks that you don't understand, and without this knowledge, it is hopeless to look for a deadlock.


    Everything should be made as simple as possible, but not simpler. Any fool can write code that a computer can understand. Good programmers write code that humans understand.


    Tuesday, August 14, 2012 10:47 AM
  • @ Mike Feng

    "Carsten said "BeginInvoke will delay the task in the method itself", ...."

    Sorry, but this is not my words. It is the words of Ignoredrei - see his post of monday 13th 1:24 AM.

    Hi Carsten,

    Sorry, my bad.

    Best regards,


    Mike Feng
    MSDN Community Support | Feedback to us
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Wednesday, August 15, 2012 12:47 AM
    Moderator