There are about 4 ways to do this:
Dispatcher, asynchronous delegate, manual multithreading, BackgroundWorker, There is also a dispatchertimer, is a timer.
Where dispatcher is the same as DispatcherTimer, it is used to simulate multi-threading by arranging task priorities in the main thread, so the substance is single-threaded
, so it is not advisable to use them for heavy load operations. When calling asynchronously, use Dispatcher.invoke (AddItem, image);
BackgroundWorker will go to the thread pool to grab a thread as a worker, switch back to the UI thread after the work is done, call the task you defined to complete the process.
Sorrento Each time a value is calculated, the worker is used. ReportProgress (PercentComplete) notifies the callback function and can update the UI in the callback function. Special
Not suitable for scenarios where you need to update a completed percentage.
These can all be combined with data binding.
① asynchronous delegate or manual multithreading
Asynchronous Delegate : Supports callback at end of thread (the first parameter of the BeginInvoke method), but does not support disconnected threads outside, and is used to update the UI.
Manual Threading : Supports external thread break (Thread.Abort method), but it is not easy to get the return value of the function. In addition, the UI cannot be updated. Because the Windows
The form uses a single-threaded apartment (STA) model, as is the case with WPF forms, the STA model means that Windows can be created on any thread, but once the window is created
The thread cannot be switched, and all function calls to it must occur on its creation thread. In particular, be careful in registering event callback functions.
usage of delegate:
[C-sharp] View plaincopy
- public class Mydelegatetest
- {
- Step 1, declaring the delegate object
- Public delegate bool MyDelegate (string name);
- This is the method we want to pass, which has the same parameters and return value types as the MyDelegate
- public static bool Mydelegatefunc (string name)
- {
- Console.WriteLine ("Hello, {0}", name);
- return ture;
- }
- public static Voidmain ()
- {
- Step 2, create the delegate object
- MyDelegate MD = new MyDelegate (MYDELEGATETEST.MYDELEGATEFUNC);
- Step 3, call delegate
- Console.WriteLine ("Result is {0}", MD ("sam1111"));
- }
- }
This method of invocation, like invoke with the delegate object, is a synchronous call that blocks the current thread. Asynchronous calls require the use of BeginInvoke:
[C-sharp] View plaincopy
- Class Program
- {
- private static int NewTask (int ms)
- {
- Console.WriteLine ("Task Start");
- Thread.Sleep (MS);
- Random random = new random ();
- int n = random. Next (10000);
- Console.WriteLine ("Mission Accomplished");
- return n;
- }
- Private delegate int newtaskdelegate (int ms);
- static void Main (string[] args)
- {
- Newtaskdelegate task = NewTask;
- IAsyncResult AsyncResult = task. BeginInvoke (+, NULL, NULL); EndInvoke method will be blocked 2
- Seconds
- Do Something Else
- int result = task. EndInvoke (AsyncResult);
- Console.WriteLine (result);
- }
- }
The BeginInvoke here is an asynchronous call that returns immediately after the run, without causing the current thread to block. But in this routine, because the NewTask
In Sleep 2 seconds, if the do Something else time does not have 2 seconds, EndInvoke will still cause the current thread to block because it waits for
NewTask execution is complete.
Can you not call EndInvoke and let it end by itself? Not very good. Because a BeginInvoke and EndInvoke must be called in pairs. Even if you do not need to return
return value, but EndInvoke still must be called, otherwise it may cause a memory leak because it is leveraging the thread pool resource. Secondly, we often call EndInvoke
To get the return value of the function.
If the BeginInvoke is used for polling, EndInvoke cannot be returned, then a variable can be used to control it:
In my application scenario, a wrapper class is defined:
[C-sharp] View plaincopy
- Class Isnetworkavailabledelegate
- {
- Private Isnetworkavailablewrapper _available;
- Private delegate void MyDelegate ();
- Private MyDelegate _dele;
- Private IAsyncResult _result;
- private bool _running = true;
- private void Tryconnect ()
- {
- while (this._running)
- {
- Try
- {
- Ping _ping = new Ping ();
- if (_ping. Send ("www.baidu.com"). Status = = ipstatus.success)
- This._available. Isnetworkavailable = true;
- Else
- This._available. Isnetworkavailable = false;
- }
- Catch
- {
- This._available. Isnetworkavailable = false;
- }
- Thread.Sleep (500);
- }
- }
- Public Isnetworkavailabledelegate (Isnetworkavailablewrapper available)
- {
- This._available = available;
- This._dele = new MyDelegate (this. Tryconnect);
- This._result = This._dele. BeginInvoke (null, NULL);
- }
- public void EndInvoke ()
- {
- This._running = false;
- This._dele. EndInvoke (This._result);
- }
- }
To be completely asynchronous with the current thread, you can use the second parameter of BeginInvoke to set a callback function after the function executes:
[C-sharp] View plaincopy
- Private delegate int mydelegate (int a);
- private int method (int a)
- {
- Thread.Sleep (10000);
- Console.WriteLine (a);
- return 100;
- }
- private void methodcompleted (IAsyncResult asyncResult)
- {
- if (AsyncResult = = null) return;
- TextBox1.Text = (asyncresult.asyncstate as MyDelegate). EndInvoke (AsyncResult). ToString ();
- }
- private void Button1_Click (object sender, EventArgs e)
- {
- MyDelegate my = method;
- IAsyncResult AsyncResult = My. BeginInvoke (methodcompleted, my);
- }
This allows the current thread to feel no more waiting at all.
Sometimes, however, the current thread wants to take advantage of the time the function executes, and then do something else after the function is done, using the WaitOne method: Reverse telecommuting.
[C-sharp] View plaincopy
- Class Program
- {
- public delegate int Binaryopdelegate (int x, int y);
- static void Main (string[] args)
- {
- Console.WriteLine ("* * * * * Async Delegate Invocation * * * * * *);
- Print out the ID of the executing thread.
- Console.WriteLine ("Main () invoked on thread {0}.",
- THREAD.CURRENTTHREAD.MANAGEDTHREADID);
- Invoke Add () on a secondary thread.
- Binaryopdelegate B = new Binaryopdelegate (ADD);
- IAsyncResult Iftar = B.begininvoke (ten, ten, NULL, NULL);
- This message would keep printing until
- The Add () method is finished.
- Wait for asynchronous delegate execution to complete with WaitOne
- while (!iftar.asyncwaithandle.waitone (), True)
- {
- Console.WriteLine ("Doing more work in Main ()!");
- }
- Obtain the result of the ADD ()
- Method is ready.
- int answer = B.endinvoke (Iftar);
- Console.WriteLine ("Ten + Ten is {0}.", answer);
- Console.ReadLine ();
- }
- #region Very Slow addition ...
- static int Add (int x, int y)
- {
- Print out the ID of the executing thread.
- Console.WriteLine ("Add () invoked on thread {0}.",
- THREAD.CURRENTTHREAD.MANAGEDTHREADID);
- Simulate an act that takes a long time
- Pause to simulate a lengthy operation.
- Thread.Sleep (5000);
- return x + y;
- }
- #endregion
- }
(PS: Using lambda syntax can also write very good sentences:)
[C-sharp] View plaincopy
- action<object> action= (obj) =>method (obj);
- Action. BeginInvoke (obj,ar=>action. EndInvoke (AR), null);
In fact, it can be more direct:
[C-sharp] View plaincopy
- New Action<object> ((obj) = method (obj)). BeginInvoke (ar=>action. EndInvoke (AR), null);
)
The main function of the Invoke method is to help you invoke the method specified by the delegate on the UI thread. The Invoke method first checks the thread that made the call (that is, the current thread
is not a UI thread, if it is, directly executes the method that the delegate points to, if not, it switches to the UI thread, and then executes the method that the delegate points to.
Calls to the manual thread:
The typical notation is:
[C-sharp] View plaincopy
- public class Procclass
- {
- private string procparameter = "";
- private string result = "";
- Public Procclass (string parameter)
- {
- Procparameter = parameter;
- }
- public void ThreadProc ()
- {
- }
- }
- Procclass ThreadProc = new Procclass ("Use thread class");
- Thread thread = new Thread (new ThreadStart (Threadproc.threadproc));
- Thread. IsBackground = true;
- Thread. Start ();
Because a function called by thread can only be parameterless and has no return value, it is usually wrapped in a class.
If a thread needs to be interruptible, it also has to deal with the UI:
[C-sharp] View plaincopy
- public class Procclass
- {
- private string procparameter = "";
- Private form1.outdelegate Delg = null;
- Public Procclass (string parameter, Form1.outdelegate Delg)
- {
- Procparameter = parameter;
- This.delg = Delg;
- }
- public void ThreadProc ()
- {
- Delg. BeginInvoke ("Use Procclass.threadproc ()", NULL, NULL);
- }
- }
- Procclass ThreadProc = new Procclass ("Use Thread class", New Outdelegate (Outtext));
- Thread thread = new Thread (new ThreadStart (Threadproc.threadproc));
- Thread. IsBackground = true;
- Thread. Start ();
"Go" multithreading Summary in C # for absolute novice C #