SoFunction
Updated on 2025-03-06

Usage and description of Invoke and BeginInvoke in C#

c# Invoke vs. BeginInvoke

Recently, when I was learning threads, I found that when the thread I created needs to access the UI interface, an exception occurs. The reason is that I am calling the controls of the main thread across threads. Therefore, there is a rule for Windows GUI programming, which is that the control data can only be manipulated by the thread that creates the control, otherwise unpredictable results may be produced.

Sometimes, we have to call the main interface controls across threads to operate, so to facilitate the problem, .net provides us with Invoke and beginInvoke

The difference between Invoke and begininvoke is that invoke will block the current thread until the invoke call is over, and begininvoke can be called asynchronously, that is, the method returns immediately after the marshaling is completed, and the delegate method will not be executed, and the caller thread will not be blocked. However, the caller can also use the EndInvoke method or other similar WaitHandle mechanism to wait for the completion of the asynchronous operation.

Let's talk about Invoke first

        // Define the delegate function. The delegate function and the delegated function must have the same return value and parameter list.        public delegate void myDelegate(string str);  
        public void _invoke_myDelegate(String str)
        {
            // invokeRequired Get a bool value to determine whether the invoke method must be called to the calling control.            // Return true if the call object is in another thread, otherwise return false            if ()
            {
               /* Action<string> action = new Action<string>(_invoke_myDelegate);*/
               // Make sure that the call object is in another thread, then call the invoke function and it will return to the thread that owns this control               // Use the delegate function to call the delegated function again, str is the parameter list of the delegate function               (new myDelegate(_invoke_myDelegate), str);
            }
            // When the delegate function is executed, it has returned to the control thread and can directly call the control label             = str;
        }

Here Invoke must wait until the delegate function call is completed before the subsequent operation is executed. Then when our delegate function performs a very time-consuming operation

In this way, the thread will be blocked, causing the user interface to be stuck. Therefore, in order to solve the problem of invoke synchronization, another type is beginInvoke

BeginInvoke

The BeginInvoke method triggers your asynchronous method, which has the same parameters as the asynchronous method you want to execute.

There are two optional parameters

  • 1. The first is that the AsyncCallback delegate is a callback method completed asynchronously.
  • 2. The second is a user-defined object, which will be passed into the callback method.

BeginInvoke returns immediately and does not wait for the asynchronous call to complete (continue to execute the following code, no need to wait).

BeginInvoke returns the IAsyncResult interface, which can be used to detect asynchronous calls.

The result of an asynchronous call is detected by the EndInvoke method. If the asynchronous call has not been completed yet, EndInvoke will block the calling thread until it completes. The EndInvoke parameter includes out and ref parameters.

No matter what, if you call beginInvoke, you must call endInvoke to end asynchronously.

So how can we know when the asynchronous ends?

There are four common methods:

  • 1. Do some other operations and then call the EndInvoke method to block the thread until the method is finished.
  • 2. Use the property, use its WaitOne method to block the thread until the WaitHandle signal is received, and then call EndInvoke.
  • 3. Check the status of the BeginInvoke return value IAsyncResult to determine whether the method is completed, and then call the EndInvoke method.
  • 4. By passing the delegate in the BeginInvoke method, call the EndInvoke method of the delegate in the callback method.
   AsyncMethodCaller caller = new AsyncMethodCaller(TestMethodAsync); // caller is a delegate function            int threadid = 0;
            //Enable asynchronous operation            IAsyncResult result = (1000, out threadid, null, null);
            for (int i = 0; i < 10; i++)
            {
                ("Other businesses" + ());
            }
            //Call EndInvoke and wait for asynchronous execution to complete            ("Waiting for the asynchronous method TestMethodAsync execution to complete");
            //Waiting for the signal of asynchronous execution to complete            //();
            //("WaitHandle signal received");            //Check the asynchronous running state continuously through loop            while (==false)
            {
                (100);
                ("Async method, running...");
            }
            //Asynchronously ends and gets the running result            string res = (out threadid, result);
            //Show the close handle            ();
            ("Close WaitHandle handle");

static string TestMethodAsync(int callDuration, out int threadId)
        {
            Stopwatch sw = new Stopwatch();
            ();
            ("Async Start");
            for (int i = 0; i < 5; i++)
            {   // Simulation time-consuming operation                (callDuration);
                ("TestMethodAsync:" + ());
            }
            ();
            threadId = ;
            return ("time consuming{0}ms.", ());
        }

Summarize

The above is personal experience. I hope you can give you a reference and I hope you can support me more.