Heim >Backend-Entwicklung >C#.Net-Tutorial >Zusammenfassung der asynchronen .NET-Programmierung ---- Codezusammenfassung der vier Implementierungsmodi
Ich war in letzter Zeit sehr beschäftigt, um einen Job zu finden und mich auch um die Projekte der Firma meines Chefs zu kümmern. Heute habe ich mir im Unternehmen eine Pause von meinem vollen Terminkalender gegönnt, um die Implementierungsmethode für asynchrone Aufruffunktionen in .NET zusammenzufassen. Bevor ich diesen Blogbeitrag geschrieben habe, habe ich meine Hausaufgaben gemacht, bevor ich mit dem Schreiben begonnen habe , damit ich im Code sprechen kann.
Der Inhalt dieses Artikels zielt darauf ab, die asynchrone Aufrufmethode klar zu erklären. Wenn es Ihnen nicht gefällt, beschweren Sie sich nicht das eine, nicht stören~
lz's Der vorherige Artikel hat kurz über Asynchronität gesprochen, hauptsächlich aus der Perspektive des Verständnisses; Zur Implementierung der asynchronen Programmierung stehen vier Methoden zur Auswahl. Diese vier Arten von Anforderungen entsprechen tatsächlich vier asynchronen Aufrufmodi, die in zwei Kategorien unterteilt sind: „Warten“ und „Rückruf“. Ich habe im Code für die vier Methoden detaillierte Kommentare abgegeben. Ich werde hier nicht auf Details eingehen.
Die erste Methode: BeginEnvoke EndEnvoke-Methode, die zur „Warten“-Methode gehört " Klasse.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace 异步调用实现方法汇总 { /// <summary> /// 异步调用方法总结: /// 1.BeginEnvoke EndEnvoke /// 当使用BeginInvoke异步调用方法时,如果方法未执行完,EndInvoke方法就会一直阻塞,直到被调用的方法执行完毕 /// </summary> class Program { public delegate void PrintDelegate(string s); static void Main(string[] args) { PrintDelegate printDelegate = Print; Console.WriteLine("主线程"); IAsyncResult result= printDelegate.BeginInvoke("Hello World.", null, null); Console.WriteLine("主线程继续执行..."); //当使用BeginInvoke异步调用方法时,如果方法未执行完,EndInvoke方法就会一直阻塞,直到被调用的方法执行完毕 printDelegate.EndInvoke(result); Console.WriteLine("Press any key to continue..."); Console.ReadKey(true); } public static void Print(string s) { Console.WriteLine("异步线程开始执行:"+s); Thread.Sleep(5000); } } }
Dinge, die Aufmerksamkeit erfordern, sind im Code vermerkt. Die Ergebnisse der Programmausführung sind wie folgt:
Zweite Methode: WaitOne. Gehört auch zur Kategorie „Warten“.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace 异步调用实现方法汇总2 { /// <summary> /// 异步调用方法总结: /// 2.WaitOne /// 可以看到,与EndInvoke类似,只是用WaitOne函数代码了EndInvoke而已。 /// </summary> class Program { public delegate void PrintDelegate(string s); static void Main(string[] args) { PrintDelegate printDelegate = Print; Console.WriteLine("主线程"); IAsyncResult result = printDelegate.BeginInvoke("Hello World.", null, null); Console.WriteLine("主线程继续执行..."); result.AsyncWaitHandle.WaitOne(-1, false); Console.WriteLine("Press any key to continue..."); Console.ReadKey(true); } public static void Print(string s) { Console.WriteLine("异步线程开始执行:" + s); Thread.Sleep(5000); } } }
Dinge, die Aufmerksamkeit erfordern, sind im Code vermerkt. Die Ergebnisse der Programmausführung sind wie folgt:
Die dritte Methode: Umfragen. Es gehört auch zur Kategorie „Warten“.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace 异步调用实现方法汇总3 { /// <summary> /// 异步调用方法总结: /// 3.轮询 /// 之前提到的两种方法,只能等下异步方法执行完毕, /// 在完毕之前没有任何提示信息,整个程序就像没有响应一样,用户体验不好, /// 可以通过检查IasyncResult类型的IsCompleted属性来检查异步调用是否完成, /// 如果没有完成,则可以适时地显示一些提示信息 /// </summary> class Program { public delegate void PrintDelegate(string s); static void Main(string[] args) { PrintDelegate printDelegate = Print; Console.WriteLine("主线程:"+Thread.CurrentThread.ManagedThreadId ); IAsyncResult result = printDelegate.BeginInvoke("Hello world.", null, null); Console.WriteLine("主线程:" + Thread.CurrentThread.ManagedThreadId + ",继续执行..."); while (!result.IsCompleted) { Console.WriteLine("."); Thread.Sleep(500); } Console.WriteLine("主线程:" + Thread.CurrentThread.ManagedThreadId + " Press any key to continue..."); Console.ReadKey(true); } public static void Print(string s) { Console.WriteLine("当前线程:" + Thread.CurrentThread.ManagedThreadId + s); Thread.Sleep(5000); } } }
Dinge, die Aufmerksamkeit erfordern, sind im Code vermerkt. Die Ergebnisse der Programmausführung sind wie folgt:
Die vierte Methode: Rückruf. Fällt definitiv in die Kategorie „Rückruf“. empfehlen! ! ! !
Die vorherigen drei Methoden können das Ausführungsergebnis erst erhalten, nachdem sie auf den Abschluss der asynchronen Methode gewartet haben, während sich der Hauptthread in einem Wartezustand befindet. Der größte Unterschied zwischen Rückrufen und ihnen besteht darin, dass der Hauptthread nicht darauf warten muss, dass der asynchrone Thread seine Arbeit abschließt, solange die Rückrufmethode beim Aufruf von BeginInvoke bereitgestellt wird Nachdem die Arbeit abgeschlossen ist, führen Sie in der Rückrufmethode die entsprechende Verarbeitung durch.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; namespace 异步调用实现方法汇总4 { /// <summary> /// 异步调用方法总结: /// 4.回调 /// 之前三种方法者在等待异步方法执行完毕后才能拿到执行的结果,期间主线程均处于等待状态。 /// 回调和它们最大的区别是,在调用BeginInvoke时只要提供了回调方法,那么主线程就不必要再等待异步线程工作完毕, /// 异步线程在工作结束后会主动调用我们提供的回调方法,并在回调方法中做相应的处理,例如显示异步调用的结果。 /// </summary> class Program { public delegate void PrintDelegate(string s); static void Main(string[] args) { PrintDelegate printDelegate = Print; Console.WriteLine("主线程."); printDelegate.BeginInvoke("Hello world.", PrintComeplete, printDelegate); Console.WriteLine("主线程继续执行..."); Console.WriteLine("Press any key to continue..."); Console.ReadKey(true); } public static void Print(string s) { Console.WriteLine("当前线程:"+s); Thread.Sleep(5000); } //回调方法要求 //1.返回类型为void //2.只有一个参数IAsyncResult public static void PrintComeplete(IAsyncResult result) { (result.AsyncState as PrintDelegate).EndInvoke(result); Console.WriteLine("当前线程结束." + result.AsyncState.ToString()); } } }
Dinge, die Aufmerksamkeit erfordern, sind im Code vermerkt. Die Ergebnisse der Programmausführung sind wie folgt:
Rufen Sie den Rückgabewert der Synchronisationsfunktion über die EndInvoke-Methode ab. Der Rückgabewert der obigen Synchronisationsmethode ist ungültig. Geben wir ein Beispiel:
using System.Diagnostics; using System.Threading; using System.Windows; namespace TestDelegateWrapper { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } private void ButtonBase_OnClick(object sender, RoutedEventArgs e) { WrapperSyncMethodAsync("ABC"); Trace.WriteLine("Main thread continue..."); } private delegate string SyncMethod1Delegate(string str); private void WrapperSyncMethodAsync(string str) { SyncMethod1Delegate syncMethod1Delegate = SyncMethod1; syncMethod1Delegate.BeginInvoke(str, x => { var result= syncMethod1Delegate.EndInvoke(x); // using the result to do something Trace.WriteLine(result); }, null); } private string SyncMethod1(string str) { Thread.Sleep(2000); return str; } } }
Die Ausgabe lautet wie folgt:
Main Thread weiter...
ABC
Die oben genannten vier Möglichkeiten zur Implementierung asynchroner Funktionsaufrufe sind sehr klar