วิธีการเรียกเมธอด Visual c# asynchronously

การแปลบทความ การแปลบทความ
หมายเลขบทความ (Article ID): 315582 - ผลิตภัณฑ์ที่เกี่ยวข้องในบทความนี้
ขยายทั้งหมด | ยุบทั้งหมด

เนื้อหาบนหน้านี้

สรุป

ทำ Framework Microsoft .NET ให้ง่ายต่อการเรียกฟังก์ชัน asynchronously การเรียกฟังก์ชัน asynchronously ทำให้ระบบปฏิบัติเหล่านั้นในแบบแบ็คกราวน์เธรดที่รองในขณะที่เรียกฟังก์ชันยังคงทำงานอื่น ๆ ในการเรียกฟังก์ชัน (แบบสมวาร) โดยทั่วไป ฟังก์ชันจะดำเนินทันทีในเธรดเดียวกับที่ทำการโทร ฟังก์ชันการเรียกรอสำหรับการเรียกให้เสร็จสมบูรณ์ และได้รับผลลัพธ์ของการเรียกก่อนที่จะดำเนินการต่อ โดย contrast เมื่อคุณทำการเรียกแบบอะซิงโครนัส คุณดึงข้อมูลผลลัพธ์ของการเรียกแบบอะซิงโครนัสในภายหลัง บทความนี้อธิบายวิธีการดังกล่าว โดยใช้ Visual c#

ความต้องการ


รายการต่อไปนี้แสดงฮาร์ดแวร์ที่แนะนำ ซอฟต์แวร์ โครงสร้างพื้นฐานของเครือข่าย และ service pack ที่จำเป็นต้องใช้:
  • Microsoft Windows 2000 หรือ Microsoft Windows XP หรือ Microsoft Windows Server 2003
  • visual Studio .NET หรือ Visual Studio 2005
บทความนี้อนุมานว่า คุณไม่คุ้นเคยกับหัวข้อต่อไปนี้:
  • วิธีการโทรศัพท์ใน Visual c#
  • วิธีการใช้ผู้รับมอบสิทธิ์

วิธีการที่ทำให้พื้นที่แบบอะซิงโครนัส

การเรียกแบบอะซิงโครนัสทำ โดยใช้ผู้รับมอบสิทธิ์ ผู้รับมอบสิทธิ์มีวัตถุที่ wraps ฟังก์ชัน ผู้รับมอบสิทธิ์ให้กับฟังก์ชันแบบซิงโครนัส และยัง ให้วิธีการสำหรับการเรียกฟังก์ชันที่ตัด asynchronously วิธีการเหล่านั้นได้BeginInvoke()และEndInvoke(). รายชื่อของพารามิเตอร์ของวิธีการเหล่านี้แตกต่างกันไปขึ้นอยู่กับลายเซ็นของฟังก์ชันที่ผู้รับมอบสิทธิ์ wraps หมายเหตุที่ Visual Studio .NET IntelliSense คุณลักษณะไม่แสดงBeginInvoke()และEndInvoke()ดังนั้นคุณไม่เห็นเหล่านั้นปรากฏอยู่ใน ฟังก์ชันแสดงรายการ ตามที่คุณพิมพ์

BeginInvoke()ถูกใช้เพื่อเริ่มต้นการเรียกแบบอะซิงโครนัส มีพารามิเตอร์เหมือนกันเป็นฟังก์ชันตัด บวกพารามิเตอร์เพิ่มเติมสองที่อธิบายในบทความนี้BeginInvoke()ส่งกลับค่าทันที และไม่รอการเรียกแบบอะซิงโครนัสให้เสร็จสมบูรณ์BeginInvoke()ส่งกลับค่าข้อIAsyncResultวัตถุ

กระบวนการEndInvoke()ใช้ฟังก์ชันการดึงข้อมูลผลลัพธ์ของการเรียกแบบอะซิงโครนัส สามารถถูกเรียกว่าเวลาใดก็ได้หลังจากBeginInvoke(). ถ้าการเรียกแบบอะซิงโครนัสไม่เสร็จได้EndInvoke()บล็อกจนกว่าจะเสร็จสมบูรณ์ พารามิเตอร์ของการEndInvoke()มีฟังก์ชันไม่เพียงพอและrefพารามิเตอร์ที่มีฟังก์ชันที่ตัด บวกIAsyncResultวัตถุที่ถูกส่งกลับโดยBeginInvoke().

ต่อไปนี้เป็นตัวอย่างของการเป็นผู้รับมอบสิทธิ์ และการBeginInvoke()และEndInvoke()วิธีการ:
// The following delegate 
delegate string MethodDelegate(int iCallTime, out int iExecThread)  ;

// will have the following BeginInvoke() and EndInvoke methods:
IAsyncResult MethodDelegate.BeginInvoke(int iCallTime, out int iExecThread, AsyncCallback cb, object AsyncState); 

string MethodDelegate.EndInvoke (out int iExecThread, IAsyncResult ar) ;
				
มีสี่วิธีทั่วไปใช้BeginInvoke()และEndInvoke()เพื่อทำการเรียกแบบอะซิงโครนัส หลังจากเรียกของคุณBeginInvoke()คุณสามารถ:
  • อีกวิธีหนึ่งคือไม่ทำงานอื่น ๆ และใช้EndInvoke().
  • ขอรับตัวWaitHandleที่ให้ไว้โดยIAsyncResultวัตถุ ใช้นั้นWaitOneวิธีการบล็อกจนถึงการWaitHandleมี signaled และเรียกใช้แล้วEndInvoke().
  • โพลIAsyncResultวัตถุการตรวจสอบเมื่อการเรียกแบบอะซิงโครนัสเสร็จสมบูรณ์แล้ว และการเรียกแล้วEndInvoke().
  • ระบบจะเรียกใช้ฟังก์ชันเรียกกลับที่คุณระบุได้ เรียกฟังก์ชันนี้เรียกกลับEndInvoke()และกระบวนการผลลัพธ์ของการเรียกแบบอะซิงโครนัสเมื่อคุณเสร็จสมบูรณ์
ตัวอย่างรหัสต่อไปนี้สาธิตเหล่านี้เรียกใช้ลวดลาย และ contrast ด้วยการทำให้การเรียกแบบสมวารโดยใช้ฟังก์ชันต่อไปนี้:
string LongRunningMethod (int iCallTime, out int iExecThread)
{
	Thread.Sleep (iCallTime) ;
	iExecThread = AppDomain.GetCurrentThreadId ();
	return "MyCallTime was " + iCallTime.ToString() ;
}

				
LongRunningMethod()จำลองการฟังก์ชันที่เรียกใช้เวลานาน โดยการใช้งาน จะส่งกลับค่าเวลาในโหมดสลีปและ ID ของเธรดที่ดำเนินการดังกล่าว ถ้าคุณเรียกการดังกล่าว asynchronously คุณพบว่า ID ของเธรดของเธรดที่กำลังจะแตกต่างจากของเธรดที่เรียก

ขั้นแรกคือการ กำหนดผู้รับมอบสิทธิ์ที่ wraps ฟังก์ชัน:
delegate string MethodDelegate(int iCallTime, out int iExecThread)  ;
				

ตัวอย่างที่ 1: เรียกวิธีการ Synchronously

ตัวอย่างนี้อธิบายวิธีการเรียกLongRunningMethod()synchronously โดยใช้ตัวMethodDelegateผู้รับมอบสิทธิ์ ตัวอย่างอื่น contrast นี้ โดยการทำให้การเรียก asynchronously
  1. เริ่ม Microsoft Visual Studio .NET หรือ Microsoft Visual Studio 2005
  2. สร้างโครงการ Visual c# คอนโซลแอพพลิเคชันใหม่ชื่อ AsyncDemo
  3. เพิ่มคลาสที่ระบุ AsyncDemo ที่กำหนดไว้เป็นดังนี้กับโครงการในแฟ้ม.cs ใหม่:
    using System;
    using System.Threading ; 
    using System.Windows.Forms ;
    
    public class AsyncDemo
    {
    	string LongRunningMethod (int iCallTime, out int iExecThread)
    	{
    		Thread.Sleep (iCallTime) ;
    		iExecThread = AppDomain.GetCurrentThreadId ();
    		return "MyCallTime was " + iCallTime.ToString() ;
    	}
    
    	delegate string MethodDelegate(int iCallTime, out int iExecThread)  ;
    
    	public void DemoSyncCall()
    	{
    		string s ;
    		int iExecThread;
    
    		// Create an instance of a delegate that wraps LongRunningMethod.
    		MethodDelegate dlgt = new MethodDelegate (this.LongRunningMethod) ;  
    			
    		// Call LongRunningMethod using the delegate.
    		s = dlgt(3000, out iExecThread);  
    			
    		MessageBox.Show (string.Format ("The delegate call returned the string:   \"{0}\", 
                                            and the thread ID {1}", s, iExecThread.ToString() ) );
    	}
    }
    					
    ในภายหลัง คลานี้อธิบายวิธีการที่ทำการเรียกแบบอะซิงโครนัส เริ่มต้นด้วย อย่างไรก็ตาม เท่านั้นประกอบด้วยการDemoSyncCall()วิธี ซึ่งอธิบายวิธีการเรียกผู้รับมอบสิทธิ์ synchronously
  4. เพิ่มรหัสต่อไปนี้ในเนื้อความของหลักฟังก์ชันที่ Visual Studio ที่สร้างโดยอัตโนมัติในโครงการของคุณ:
    static void Main(string[] args)
    {
    	AsyncDemo ad = new AsyncDemo () ;
    	ad.DemoSyncCall() ;
    }
    					
  5. กด CTRL + F5 เพื่อเรียกใช้โปรแกรมประยุกต์ของคุณ

ตัวอย่างที่ 2: เรียกวิธี A Asynchronously โดยใช้การEndInvoke()เรียกใช้ลวดลาย

ในส่วนนี้ ตัวอย่าง invokes วิธีการเดียวกัน asynchronously รูปแบบการโทรที่ใช้เป็นการ โทรBeginInvokeไม่ทำงานเธรดการหลัก และบางเรียกแล้วEndInvoke(). หมายเหตุที่EndInvoke()ไม่เกิดจนกว่าการเรียกแบบอะซิงโครนัสเสร็จเรียบร้อยแล้ว รูปแบบการเรียกนี้มีประโยชน์เมื่อคุณต้องการให้มีเธรดที่เรียกทำงานในเวลาเดียวกันที่กำลังดำเนินการการเรียกแบบอะซิงโครนัส มีการทำงานที่เกิดขึ้นในเวลาเดียวกันสามารถปรับปรุงประสิทธิภาพการทำงานของโปรแกรมประยุกต์จำนวนมาก งานทั่วไปจะเรียกใช้ asynchronously ด้วยวิธีนี้มีการดำเนินงานของแฟ้มหรือเครือข่าย
  1. เพิ่มวิธีการตั้งชื่อDemoEndInvoke()ไปAsyncDemoคลาสที่ กระบวนการDemoEndInvokeฟังก์ชันอธิบายวิธีการเรียกผู้รับมอบสิทธิ์ asynchronously
    public void DemoEndInvoke()
    {
    	MethodDelegate dlgt = new MethodDelegate (this.LongRunningMethod) ;
    	string s ;
    	int iExecThread;
    
    	// Initiate the asynchronous call.
    	IAsyncResult ar = dlgt.BeginInvoke(3000, out iExecThread, null, null);  
    
    	// Do some useful work here. This would be work you want to have
    	// run at the same time as the asynchronous call.
    
    	// Retrieve the results of the asynchronous call.
    	s = dlgt.EndInvoke (out iExecThread, ar) ;  
    
    	MessageBox.Show (string.Format ("The delegate call returned the string:   \"{0}\", 
                                   and the number {1}", s, iExecThread.ToString() ) );
    }
    					
  2. รหัสแหล่งที่มาสำหรับแก้ไขหลักเพื่อที่จะประกอบด้วยรหัสต่อไปนี้:
    static void Main(string[] args)
    {
    	AsyncDemo ad = new AsyncDemo () ;
    	ad.DemoEndInvoke() ;
    }
    					
  3. กด CTRL + F5 เพื่อเรียกใช้โปรแกรมประยุกต์ของคุณ

ตัวอย่างที่ 3: การเรียกวิธี A Asynchronously และการใช้การ WaitHandle การรอสำหรับการเรียกไปที่สมบูรณ์


ในส่วนนี้ ตัวอย่างเรียกเมธอด asynchronously และรอสำหรับการWaitHandleก่อนเรียกของคุณEndInvoke(). กระบวนการIAsyncResultส่งกลับโดยBeginInvoke()มีข้อAsyncWaitHandleคุณสมบัติ ส่งกลับค่าของคุณสมบัตินี้เป็นWaitHandleที่อยู่ signaled เมื่อการเรียกแบบอะซิงโครนัสเสร็จสมบูรณ์ กำลังรอการWaitHandleเป็นเทคนิคหนึ่งของการซิงโครไนส์เธรดที่พบโดยทั่วไป เธรดที่เรียกที่รอในนั้นWaitHandleโดยWaitOne()วิธีการนี้WaitHandle.WaitOne()บล็อกจนถึงการWaitHandleมี signaled เมื่อWaitOne()ส่งกลับค่า คุณสามารถทำงานบางอย่างเพิ่มเติมได้ก่อนที่คุณเรียกใช้EndInvoke(). ในตัวอย่างก่อนหน้านี้ เทคนิคนี้จะเป็นประโยชน์สำหรับการดำเนินการทำงานแฟ้มหรือเครือข่ายที่มิฉะนั้นจะบล็อกเธรดหลักที่เรียก
  1. เพิ่มชื่อฟังก์ชันDemoWaitHandle()ไปAsyncDemoคลาสที่ กระบวนการDemoWaitHandle()ฟังก์ชันอธิบายวิธีการเรียกผู้รับมอบสิทธิ์ asynchronously
    public void DemoWaitHandle ()
    {
    	string s ;
    	int iExecThread;
    
    	MethodDelegate dlgt = new MethodDelegate (this.LongRunningMethod) ;
    
    	// Initiate the asynchronous call.
    	IAsyncResult ar = dlgt.BeginInvoke(3000, out iExecThread, null, null); 
    
    	// Do some useful work here. This would be work you want to have
    	// run at the same time as the asynchronous call.
    
    	// Wait for the WaitHandle to become signaled.
    	ar.AsyncWaitHandle.WaitOne() ;
    
    	// Get the results of the asynchronous call.
    	s = dlgt.EndInvoke (out iExecThread, ar) ;
    			
    	MessageBox.Show (string.Format ("The delegate call returned the string:   \"{0}\", 
                                     and the number {1}", s, iExecThread.ToString() ) );
    }
    					
  2. รหัสแหล่งที่มาสำหรับแก้ไขหลักเพื่อที่จะประกอบด้วยรหัสต่อไปนี้:
    static void Main(string[] args)
    {
    	AsyncDemo ad = new AsyncDemo () ;
    	ad.DemoWaitHandle () ;
    }
    					
  3. กด CTRL + F5 เพื่อเรียกใช้โปรแกรมประยุกต์ของคุณ

ตัวอย่างที่ 4: เรียกวิธี A Asynchronously โดยใช้รูปแบบการติดต่อ Polling

ในส่วนนี้ polls ตัวอย่างนี้IAsyncResultวัตถุเพื่อค้นหาเมื่อการเรียกแบบอะซิงโครนัสเสร็จเรียบร้อยแล้ว กระบวนการIAsyncResultวัตถุที่ถูกส่งกลับโดยBeginInvoke()มีข้อIsCompletedคุณสมบัติที่ส่งคืนTrueหลังจากการเรียกแบบอะซิงโครนัสเสร็จสมบูรณ์ คุณสามารถเรียกแล้วEndInvoke(). รูปแบบการเรียกนี้เป็นประโยชน์ในกรณีที่โปรแกรมประยุกต์ของคุณทำงานที่ต่อเนื่องที่คุณต้องการไม่ได้ถูกบล็อก โดยการเรียกฟังก์ชันแบบรันเป็นเวลานาน โปรแกรมประยุกต์ของ Microsoft Windows ที่เป็นตัวอย่างนี้ เธรดหลักของแอพลิเคชัน Windows สามารถดำเนินต่อการจัดการผู้ใช้ในการป้อนข้อมูลในขณะที่ดำเนินการการเรียกแบบอะซิงโครนัส คุณสามารถตรวจสอบเป็นระยะ ๆIsCompletedเมื่อต้องการดูว่า การโทรเสร็จสมบูรณ์แล้ว โปรแกรมเรียกEndInvokeเมื่อIsCompletedส่งกลับค่าTrue. เนื่องจากEndInvoke()บล็อกจนกว่าการดำเนินการแบบอะซิงโครนัสเสร็จสมบูรณ์แล้ว แอพลิเคชันไม่เรียกนั้นจนกว่าจะทราบว่า การดำเนินการเสร็จสมบูรณ์
  1. เพิ่มชื่อฟังก์ชันDemoPolling()ไปAsyncDemoคลาสที่ กระบวนการDemoPolling()ฟังก์ชันอธิบายวิธีการเรียกผู้รับมอบสิทธิ์ asynchronously และใช้ polling เพื่อดูว่ากระบวนการเสร็จสมบูรณ์
    public void DemoPolling()
    {
    	MethodDelegate dlgt = new MethodDelegate (this.LongRunningMethod) ;
    	string s ;
    	int iExecThread;
    
    	// Initiate the asynchronous call.
    	IAsyncResult ar = dlgt.BeginInvoke(3000, out iExecThread, null, null); 
    
    	// Poll IAsyncResult.IsCompleted
    	while(ar.IsCompleted == false)
    	{
    		Thread.Sleep (10) ;  // pretend to so some useful work
    	}
    	s = dlgt.EndInvoke (out iExecThread, ar) ;
    
    	MessageBox.Show (string.Format ("The delegate call returned the string:   \"{0}\", 
                                    and the number {1}", s, iExecThread.ToString() ) );
    }
    
    					
  2. รหัสแหล่งที่มาสำหรับแก้ไขหลัก. แทนเนื้อหาของฟังก์ชันที่ มีรหัสต่อไปนี้:
    static void Main(string[] args)
    {
    	AsyncDemo ad = new AsyncDemo () ;
    	ad.DemoPolling () ;
    }
    					
  3. กด CTRL + F5 เพื่อเรียกใช้โปรแกรมประยุกต์ของคุณ

ตัวอย่างที่ 5: กำลังใช้การเรียกกลับเมื่อวิธีการแบบอะซิงโครนัสเสร็จสมบูรณ์

ในส่วนนี้ ตัวอย่างให้ผู้รับมอบสิทธิ์การเรียกกลับไปBeginInvoke()ฟังก์ชันที่ระบบจะดำเนินการเมื่อการเรียกแบบอะซิงโครนัสเสร็จสมบูรณ์ การเรียกการเรียกกลับEndInvoke()และกระบวนการผลลัพธ์ของการเรียกแบบอะซิงโครนัส รูปแบบการเรียกนี้เป็นประโยชน์ในกรณีที่เธรดที่เริ่มการเรียกแบบอะซิงโครนัสไม่จำเป็นต้องดำเนินการผลลัพธ์ของการโทร ระบบ invokes เรียกกลับบนเธรดอื่นที่ไม่ใช่เธรด initiating เมื่อการเรียกแบบอะซิงโครนัสเสร็จสมบูรณ์

เมื่อต้องการใช้รูปแบบการเรียกนี้ คุณต้องส่งผู้รับมอบสิทธิ์ของชนิดAsyncCallbackเป็นพารามิเตอร์วินาทีในล่าสุดของการBeginInvoke()ฟังก์ชันBeginInvoke()นอกจากนี้ยัง มีพารามิเตอร์ขั้นสุดท้ายของชนิดวัตถุที่คุณสามารถส่งวัตถุใด ๆ วัตถุนี้ไม่พร้อมใช้งานฟังก์ชันการเรียกกลับของคุณเมื่อมีการเรียกใช้ ใช้หนึ่งที่สำคัญสำหรับพารามิเตอร์นี้เป็นการ ส่งต่อผู้รับมอบสิทธิ์ที่ใช้ในการเริ่มต้นการโทร สามารถใช้ฟังก์ชันเรียกกลับแล้วEndInvoke()การทำงานของผู้รับมอบสิทธิ์นั้นเพื่อทำการโทร รูปแบบการเรียกนี้จะแสดงด้านล่าง
  1. เพิ่มการสองวิธีการตั้งชื่อDemoCallback()และMyAsyncCallback()ไปAsyncDemoคลาสที่ กระบวนการDemoCallback()วิธีแสดงวิธีการเรียกผู้รับมอบสิทธิ์ asynchronously โปรแกรมจะใช้เป็นผู้รับมอบสิทธิ์เพื่อที่ตัดการMyAsyncCallback()วิธี ซึ่งระบบเรียกเมื่อการดำเนินการแบบอะซิงโครนัสเสร็จสมบูรณ์MyAsyncCallback()การเรียกEndInvoke().
    public void DemoCallback()
    {
    	MethodDelegate dlgt = new MethodDelegate (this.LongRunningMethod) ;
    	string s ;
    	int iExecThread;
    
    	// Create the callback delegate.
    	AsyncCallback cb = new AsyncCallback(MyAsyncCallback);
    
    	// Initiate the Asynchronous call passing in the callback delegate
    	// and the delegate object used to initiate the call.
    	IAsyncResult ar = dlgt.BeginInvoke(3000, out iExecThread, cb, dlgt); 
    }
    
    public void MyAsyncCallback(IAsyncResult ar)
    {
    	string s ;
    	int iExecThread ;
    
    	// Because you passed your original delegate in the asyncState parameter
    	// of the Begin call, you can get it back here to complete the call.
    	MethodDelegate dlgt = (MethodDelegate) ar.AsyncState;
    
    	// Complete the call.
    	s = dlgt.EndInvoke (out iExecThread, ar) ;
    
    	MessageBox.Show (string.Format ("The delegate call returned the string:   \"{0}\", 
                                    and the number {1}", s, iExecThread.ToString() ) );
    }
    
    					
  2. รหัสแหล่งที่มาสำหรับแก้ไขหลัก. แทนเนื้อหาของฟังก์ชันที่ มีรหัสต่อไปนี้:
    static void Main(string[] args)
    {
    	AsyncDemo ad = new AsyncDemo () ;
    	ad.DemoCallback() ;
    }
    					
  3. กด CTRL + F5 เพื่อเรียกใช้โปรแกรมประยุกต์ของคุณ

คุณสมบัติ

หมายเลขบทความ (Article ID): 315582 - รีวิวครั้งสุดท้าย: 13 มกราคม 2554 - Revision: 4.0
ใช้กับ
  • Microsoft Visual Studio .NET 2002 Professional Edition
  • Microsoft Visual C# .NET 2002 Standard Edition
  • Microsoft Visual C# 2005 Express Edition
Keywords: 
kbhowtomaster kbmt KB315582 KbMtth
แปลโดยคอมพิวเตอร์
ข้อมูลสำคัญ: บทความนี้แปลโดยซอฟต์แวร์การแปลด้วยคอมพิวเตอร์ของ Microsoft แทนที่จะเป็นนักแปลที่เป็นบุคคล Microsoft มีบทความที่แปลโดยนักแปลและบทความที่แปลด้วยคอมพิวเตอร์ เพื่อให้คุณสามารถเข้าถึงบทความทั้งหมดในฐานความรู้ของเรา ในภาษาของคุณเอง อย่างไรก็ตาม บทความที่แปลด้วยคอมพิวเตอร์นั้นอาจมีข้อบกพร่อง โดยอาจมีข้อผิดพลาดในคำศัพท์ รูปแบบการใช้ภาษาและไวยากรณ์ เช่นเดียวกับกรณีที่ชาวต่างชาติพูดผิดเมื่อพูดภาษาของคุณ Microsoft ไม่มีส่วนรับผิดชอบต่อความคลาดเคลื่อน ความผิดพลาดหรือความเสียหายที่เกิดจากการแปลเนื้อหาผิดพลาด หรือการใช้บทแปลของลูกค้า และ Microsoft มีการปรับปรุงซอฟต์แวร์การแปลด้วยคอมพิวเตอร์อยู่เป็นประจำ
ต่อไปนี้เป็นฉบับภาษาอังกฤษของบทความนี้:315582

ให้ข้อเสนอแนะ

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com