Use the delegated BeginInvoke method to perform operations on complex tasks, and delegate begininvoke

Source: Internet
Author: User

Use the delegated BeginInvoke method to perform operations on complex tasks, and delegate begininvoke

Now, if I have such a form (including a progress bar and a button and two text boxes), enter a number in the first text box to perform a factorial operation. During this process, the progress bar is consistent with the operation progress, you can also perform other work (such as input) in the second text box ). In addition to using BackGroundWorker, asynchronous Invoke can also be used to deal with such a problem:
First, let's look at the interface and the corresponding code:
[Interface]

[Code]

[C #]
Namespace CSharp
{
Public partial class Form1: Form
{
Long result = 1;

Long PGo (int endnum)
{
While (progressBar1.Value <= endnum)
{
Result * = endnum;
ProgressBar1.Value + = 1;
Thread. Sleep (1000 );
Endnum --;
}
Return result;
}

Public Form1 ()
{
InitializeComponent ();
}
Private void Form1_Load (object sender, EventArgs e)
{

}

Private void button#click (object sender, EventArgs e)
{
ProgressBar1.Maximum = Convert. ToInt32 (textBox1.Text );
Func <int, long> a = new Func <int, long> (PGo );

// BeginInvoke starts the background thread for Loop
Var result = a. BeginInvoke
(
Convert. ToInt32 (textBox1.Text ),
// If the loop is completed, execute this delegate
Delegate (IAsyncResult r)
{
If (r. IsCompleted)
{
MessageBox. Show ("Finished! ");
TextBox1.Text = (r. AsyncState as Func <int, long>). EndInvoke (r). ToString ();
}
},
);

// The result. EndInvoke cannot be used. This method will cause the current process to crash until the background thread is finished. Because the main WinForm thread does not automatically close
// This thread is not required, but the console program must! Because the console process is "instantaneous ".
}
}
}
[VB. NET]
Namespace CSharp
Public Partial Class Form1
Inherits Form
Private result As Long = 1

Private Function PGo (endnum As Integer) As Long
While progressBar1.Value <= endnum
Result * = endnum
ProgressBar1.Value + = 1
Thread. Sleep (1000)
Endnum-= 1
End While
Return result
End Function

Public Sub New ()
InitializeComponent ()
End Sub
Private Sub Form1_Load (sender As Object, e As EventArgs)

End Sub

Private Sub button#click (sender As Object, e As EventArgs)
ProgressBar1.Maximum = Convert. ToInt32 (textBox1.Text)
Dim a As New Func (Of Integer, Long) (AddressOf PGo)

'Inininvoke first starts the background thread for Loop
'If the loop is completed, run the delegate www.2cto.com.
Dim result = a. BeginInvoke (Convert. ToInt32 (textBox1.Text), Function (r As IAsyncResult) Do
If r. IsCompleted Then
MessageBox. Show ("Finished! ")
TextBox1.Text = TryCast (r. AsyncState, Func (Of Integer, Long). EndInvoke (r). ToString ()
End If
End Function,)
'The result. EndInvoke cannot be used. This method will cause the current process to crash until the background thread is finished. Because the main WinForm thread does not automatically close
'This thread is not required, but the console program must! Because the console process is "instantaneous ".
End Sub
End Class
End Namespace
Some key parts are explained:
1) BeginInvoke: This method executes the method pointed to by the delegate asynchronously. The so-called "Asynchronous" means that the result does not appear directly like calling the "Invoke" method. BeginInvoke will open up a new thread internally (Note: it is a background thread !) Execute this delegate method. Because it is a background thread, if the main program is closed or stopped, it will be automatically terminated no matter whether the background thread's task is completed or not. In this example, because it is a WinForm, once the main thread is run, it will not end automatically, but for programs such as the console, if the console program uses the BeginInvoke method, the corresponding EndInvoke must be called later. The EndInvoke method blocks the current process until BeginInvoke finishes executing all the delegate methods and returns a result directly. For example:
[C #]
Namespace CSharp
{
Public class Program
{
Int Fun ()
{
Console. WriteLine ("This is a fun function with a return value ...... ");
Return 1;
}

Static void Main (string [] args)
{
Func <int> fun = new Program (). Fun;
// A new thread is created here, which is run by background threads.
Var r = fun. BeginInvoke (null, null );
// Here Thread. Sleep (10) cannot be omitted; otherwise, the background Thread has no chance to be executed.
While (! R. IsCompleted) {Thread. Sleep (10 );}
// This cannot be omitted because any background thread is attached to the main thread. After the main thread is stopped, the background thread is automatically disabled.
Console. WriteLine (fun. EndInvoke (r ));
}
}
}
[VB. NET]
Namespace CSharp
Public Class Program
Private Function Fun () As Integer
Console. WriteLine ("This is a fun function with a return value ...... ")
Return 1
End Function

Private Shared Sub Main (args As String ())
Dim fun As Func (Of Integer) = AddressOf New Program (). Fun
'A new thread is created here, all of which are running in the background.
Dim r = fun. BeginInvoke (Nothing, Nothing)
'Here Thread. Sleep (10) cannot be omitted; otherwise, the background Thread has no chance to be executed.
While Not r. IsCompleted
Thread. Sleep (10)
End While
'This cannot be omitted because any background thread is attached to the main thread. After the main thread is stopped, the background thread is automatically disabled.
Console. WriteLine (fun. EndInvoke (r ))
End Sub
End Class
End Namespace
Note that "While…" is added ......" The judgment part-Because BeginInvoke returns an IAsyncResult interface, which contains an IsCompleted Boolean attribute: This attribute indicates whether the newly opened thread has completed executing all the delegate code. Because it is asynchronous (to detect the completion of a new thread), we cannot directly obtain this situation from the main thread. Naturally, we can only make a "dead loop" judgment on IsCompleted in the main thread, and add the Sleep code (this cannot be omitted; otherwise, the ininvoke subthread has no chance to be executed and is stuck in the main thread ). If IsCompleted = True, run EndInvoke to output the result immediately.
Of course, the while section can be omitted completely, but it looks more formal. Even if the while section is not displayed to judge the IsCompleted attribute, endInvoke will also block the main thread from continuing -- until the execution is complete and the output result ends.
In addition: While ...... This section and EndInvoke cannot be ignored; otherwise, no results can be output! (Because in the console, the main thread that does not call EndInvoke will not be blocked. Once the execution is completed, the program will be terminated, and the background thread will be finished ).
In the WinForm example, you also noticed that the use of IAsyncResult interface parameters and the usage of an object -- BeginInvoke is usually automatically generated based on the delegate, roughly as follows:
BeginInvoke (parameter 1 ,...... Parameter N, IAsyncResult, objectvalue)
1) parameter 1 ...... Parameter N: All parameters are optional. It depends on whether there are parameters and the number of parameters in the original definition of the Delegate. (if only one parameter is required for the delegate, only one BeginInvoke parameter is generated ).
2) IAsyncResult: After the BeginInvoke method is executed, an internal signal will be sent to inform that IAsyncResult has been executed (the IsCompleted of IAsyncResult is also set to True ).
3) objectvalue: an optional parameter.
As mentioned earlier, EndInvoke is automatically executed and generated after the execution of -- BeginInvoke (when IsCompleted is set to True. Therefore, we can complete the task by setting objectvalue to the delegated instance and passing in BeginInvoke, and then executing EndInvoke in IAsyncResult.
Because the main WinForm thread does not terminate automatically, you cannot call EndInvoke outside the console. Otherwise, the main interface will go down (until all asynchronous methods are executed) and should be executed in IAsyncResult ).

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.