ทำ 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
- เริ่ม Microsoft Visual Studio .NET หรือ Microsoft Visual Studio 2005
- สร้างโครงการ Visual c# คอนโซลแอพพลิเคชันใหม่ชื่อ AsyncDemo
- เพิ่มคลาสที่ระบุ 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 - เพิ่มรหัสต่อไปนี้ในเนื้อความของหลักฟังก์ชันที่ Visual Studio ที่สร้างโดยอัตโนมัติในโครงการของคุณ:
static void Main(string[] args)
{
AsyncDemo ad = new AsyncDemo () ;
ad.DemoSyncCall() ;
}
- กด CTRL + F5 เพื่อเรียกใช้โปรแกรมประยุกต์ของคุณ
ตัวอย่างที่ 2: เรียกวิธี A Asynchronously โดยใช้การEndInvoke()เรียกใช้ลวดลาย
ในส่วนนี้ ตัวอย่าง invokes วิธีการเดียวกัน asynchronously รูปแบบการโทรที่ใช้เป็นการ โทร
BeginInvokeไม่ทำงานเธรดการหลัก และบางเรียกแล้ว
EndInvoke(). หมายเหตุที่
EndInvoke()ไม่เกิดจนกว่าการเรียกแบบอะซิงโครนัสเสร็จเรียบร้อยแล้ว รูปแบบการเรียกนี้มีประโยชน์เมื่อคุณต้องการให้มีเธรดที่เรียกทำงานในเวลาเดียวกันที่กำลังดำเนินการการเรียกแบบอะซิงโครนัส มีการทำงานที่เกิดขึ้นในเวลาเดียวกันสามารถปรับปรุงประสิทธิภาพการทำงานของโปรแกรมประยุกต์จำนวนมาก งานทั่วไปจะเรียกใช้ asynchronously ด้วยวิธีนี้มีการดำเนินงานของแฟ้มหรือเครือข่าย
- เพิ่มวิธีการตั้งชื่อ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() ) );
}
- รหัสแหล่งที่มาสำหรับแก้ไขหลักเพื่อที่จะประกอบด้วยรหัสต่อไปนี้:
static void Main(string[] args)
{
AsyncDemo ad = new AsyncDemo () ;
ad.DemoEndInvoke() ;
}
- กด CTRL + F5 เพื่อเรียกใช้โปรแกรมประยุกต์ของคุณ
ตัวอย่างที่ 3: การเรียกวิธี A Asynchronously และการใช้การ WaitHandle การรอสำหรับการเรียกไปที่สมบูรณ์
ในส่วนนี้ ตัวอย่างเรียกเมธอด asynchronously และรอสำหรับการ
WaitHandleก่อนเรียกของคุณ
EndInvoke(). กระบวนการ
IAsyncResultส่งกลับโดย
BeginInvoke()มีข้อ
AsyncWaitHandleคุณสมบัติ ส่งกลับค่าของคุณสมบัตินี้เป็น
WaitHandleที่อยู่ signaled เมื่อการเรียกแบบอะซิงโครนัสเสร็จสมบูรณ์ กำลังรอการ
WaitHandleเป็นเทคนิคหนึ่งของการซิงโครไนส์เธรดที่พบโดยทั่วไป เธรดที่เรียกที่รอในนั้น
WaitHandleโดย
WaitOne()วิธีการนี้
WaitHandle.
WaitOne()บล็อกจนถึงการ
WaitHandleมี signaled เมื่อ
WaitOne()ส่งกลับค่า คุณสามารถทำงานบางอย่างเพิ่มเติมได้ก่อนที่คุณเรียกใช้
EndInvoke(). ในตัวอย่างก่อนหน้านี้ เทคนิคนี้จะเป็นประโยชน์สำหรับการดำเนินการทำงานแฟ้มหรือเครือข่ายที่มิฉะนั้นจะบล็อกเธรดหลักที่เรียก
- เพิ่มชื่อฟังก์ชัน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() ) );
}
- รหัสแหล่งที่มาสำหรับแก้ไขหลักเพื่อที่จะประกอบด้วยรหัสต่อไปนี้:
static void Main(string[] args)
{
AsyncDemo ad = new AsyncDemo () ;
ad.DemoWaitHandle () ;
}
- กด CTRL + F5 เพื่อเรียกใช้โปรแกรมประยุกต์ของคุณ
ตัวอย่างที่ 4: เรียกวิธี A Asynchronously โดยใช้รูปแบบการติดต่อ Polling
ในส่วนนี้ polls ตัวอย่างนี้
IAsyncResultวัตถุเพื่อค้นหาเมื่อการเรียกแบบอะซิงโครนัสเสร็จเรียบร้อยแล้ว กระบวนการ
IAsyncResultวัตถุที่ถูกส่งกลับโดย
BeginInvoke()มีข้อ
IsCompletedคุณสมบัติที่ส่งคืน
Trueหลังจากการเรียกแบบอะซิงโครนัสเสร็จสมบูรณ์ คุณสามารถเรียกแล้ว
EndInvoke(). รูปแบบการเรียกนี้เป็นประโยชน์ในกรณีที่โปรแกรมประยุกต์ของคุณทำงานที่ต่อเนื่องที่คุณต้องการไม่ได้ถูกบล็อก โดยการเรียกฟังก์ชันแบบรันเป็นเวลานาน โปรแกรมประยุกต์ของ Microsoft Windows ที่เป็นตัวอย่างนี้ เธรดหลักของแอพลิเคชัน Windows สามารถดำเนินต่อการจัดการผู้ใช้ในการป้อนข้อมูลในขณะที่ดำเนินการการเรียกแบบอะซิงโครนัส คุณสามารถตรวจสอบเป็นระยะ ๆ
IsCompletedเมื่อต้องการดูว่า การโทรเสร็จสมบูรณ์แล้ว โปรแกรมเรียก
EndInvokeเมื่อ
IsCompletedส่งกลับค่า
True. เนื่องจาก
EndInvoke()บล็อกจนกว่าการดำเนินการแบบอะซิงโครนัสเสร็จสมบูรณ์แล้ว แอพลิเคชันไม่เรียกนั้นจนกว่าจะทราบว่า การดำเนินการเสร็จสมบูรณ์
- เพิ่มชื่อฟังก์ชัน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() ) );
}
- รหัสแหล่งที่มาสำหรับแก้ไขหลัก. แทนเนื้อหาของฟังก์ชันที่ มีรหัสต่อไปนี้:
static void Main(string[] args)
{
AsyncDemo ad = new AsyncDemo () ;
ad.DemoPolling () ;
}
- กด CTRL + F5 เพื่อเรียกใช้โปรแกรมประยุกต์ของคุณ
ตัวอย่างที่ 5: กำลังใช้การเรียกกลับเมื่อวิธีการแบบอะซิงโครนัสเสร็จสมบูรณ์
ในส่วนนี้ ตัวอย่างให้ผู้รับมอบสิทธิ์การเรียกกลับไป
BeginInvoke()ฟังก์ชันที่ระบบจะดำเนินการเมื่อการเรียกแบบอะซิงโครนัสเสร็จสมบูรณ์ การเรียกการเรียกกลับ
EndInvoke()และกระบวนการผลลัพธ์ของการเรียกแบบอะซิงโครนัส รูปแบบการเรียกนี้เป็นประโยชน์ในกรณีที่เธรดที่เริ่มการเรียกแบบอะซิงโครนัสไม่จำเป็นต้องดำเนินการผลลัพธ์ของการโทร ระบบ invokes เรียกกลับบนเธรดอื่นที่ไม่ใช่เธรด initiating เมื่อการเรียกแบบอะซิงโครนัสเสร็จสมบูรณ์
เมื่อต้องการใช้รูปแบบการเรียกนี้ คุณต้องส่งผู้รับมอบสิทธิ์ของชนิด
AsyncCallbackเป็นพารามิเตอร์วินาทีในล่าสุดของการ
BeginInvoke()ฟังก์ชัน
BeginInvoke()นอกจากนี้ยัง มีพารามิเตอร์ขั้นสุดท้ายของชนิด
วัตถุที่คุณสามารถส่งวัตถุใด ๆ วัตถุนี้ไม่พร้อมใช้งานฟังก์ชันการเรียกกลับของคุณเมื่อมีการเรียกใช้ ใช้หนึ่งที่สำคัญสำหรับพารามิเตอร์นี้เป็นการ ส่งต่อผู้รับมอบสิทธิ์ที่ใช้ในการเริ่มต้นการโทร สามารถใช้ฟังก์ชันเรียกกลับแล้ว
EndInvoke()การทำงานของผู้รับมอบสิทธิ์นั้นเพื่อทำการโทร รูปแบบการเรียกนี้จะแสดงด้านล่าง
- เพิ่มการสองวิธีการตั้งชื่อ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() ) );
}
- รหัสแหล่งที่มาสำหรับแก้ไขหลัก. แทนเนื้อหาของฟังก์ชันที่ มีรหัสต่อไปนี้:
static void Main(string[] args)
{
AsyncDemo ad = new AsyncDemo () ;
ad.DemoCallback() ;
}
- กด 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
| kbhowtomaster kbmt KB315582 KbMtth |
แปลโดยคอมพิวเตอร์ข้อมูลสำคัญ: บทความนี้แปลโดยซอฟต์แวร์การแปลด้วยคอมพิวเตอร์ของ Microsoft แทนที่จะเป็นนักแปลที่เป็นบุคคล Microsoft มีบทความที่แปลโดยนักแปลและบทความที่แปลด้วยคอมพิวเตอร์ เพื่อให้คุณสามารถเข้าถึงบทความทั้งหมดในฐานความรู้ของเรา ในภาษาของคุณเอง อย่างไรก็ตาม บทความที่แปลด้วยคอมพิวเตอร์นั้นอาจมีข้อบกพร่อง โดยอาจมีข้อผิดพลาดในคำศัพท์ รูปแบบการใช้ภาษาและไวยากรณ์ เช่นเดียวกับกรณีที่ชาวต่างชาติพูดผิดเมื่อพูดภาษาของคุณ Microsoft ไม่มีส่วนรับผิดชอบต่อความคลาดเคลื่อน ความผิดพลาดหรือความเสียหายที่เกิดจากการแปลเนื้อหาผิดพลาด หรือการใช้บทแปลของลูกค้า และ Microsoft มีการปรับปรุงซอฟต์แวร์การแปลด้วยคอมพิวเตอร์อยู่เป็นประจำ
ต่อไปนี้เป็นฉบับภาษาอังกฤษของบทความนี้:
315582
(http://support.microsoft.com/kb/315582/en-us/
)