مشاركة عبر


استدعاء وظائف متزامن بشكل غير متزامن

تمكين إطار عمل.NET إلى استدعاء أي أسلوب بشكل غير متزامن. إلى القيام بذلك قم بتحديد مفوض باستخدام نفس توقيع كالأسلوب الذي تريده إلى استدعاء؛ الشائعة تعرف auإلىmatically وقت التشغيل للغة BeginInvoke EndInvokeوظائف لهذا التفويض، باستخدام التواقيع المناسبة.

ملاحظةملاحظة

غير متزامنة تفويض المكالمات، وبشكل خاص في BeginInvoke EndInvokeوظائف، غير معتمدة في إطار عمل ".NET ضغط".

BeginInvokeأسلوب يبدأ باستدعاء غير متزامن. وليس له نفس المعلمات أسلوب أنك تريد تنفيذ بشكل غير متزامن، بالإضافة إلى معلمتين من معلمات اختيارية إضافى. معلمة الأولى هو AsyncCallbackالمفوض تشير إلى أسلوب إلى يمكن استدعاء عند إكمال الاستدعاء غير متزامن. معلمة ثانية هو كائن معرف من قبل مستخدم الذي يقوم بتمرير المعلومات في رد الاتصال أسلوب. BeginInvokeترجع مباشرة لا ينتظر الاستدعاء غير متزامن إلى كاملة. BeginInvokeإرجاعIAsyncResult، التي يمكن استخدامها لمراقبة تقدم غير متزامن يتصل.

EndInvokeأسلوب استرداد نتائج غير متزامن يتصل. يمكن استدعاء أي وقت بعد BeginInvoke. في حالة الاستدعاء غير متزامن غير مكتمل، EndInvokeيمنع مؤشر ترابط استدعاء حتى يتم مكتمل. The parameters of EndInvoke include the out and ref parameters (<Out> ByRef and ByRef in Visual Basic) of the method that you want to execute asynchronously, plus the IAsyncResult returned by BeginInvoke.

ملاحظةملاحظة

ميزة "التحسس الذكي" في Visual Studio 2005عرض المعلمات BeginInvokeو EndInvoke.إذا لم تكن تستخدم ‏‫Visual Studio أو أداة مماثلة، أو إذا كنت تستخدم C# مع Visual Studio 2005، راجع غير متزامن نظرة عامة حول البرمجةلوصف معلمات المعرفة لهذه الأساليب.

أمثلة تعليمات برمجية في هذه إلى pic شرح أربع طرق عام إلى استخدام BeginInvokeو EndInvokeإلى إجراء استدعاءات غير متزامن. بعد استدعاء BeginInvokeيمكنك القيام بما يلي:

  • قم بعمل بعض و ثم استدعاء EndInvokeإلى حظر حتى إتمام المكالمة.

  • الحصول على WaitHandleاستخدام IAsyncResult.AsyncWaitHandleخاصية، استخدام به WaitOneأسلوب لتنفيذ حظر حتى WaitHandleهو إليه بصوت، ثم قم باستدعاء EndInvoke.

  • الاستقصاء IAsyncResultالتي يتم إرجاعها بواسطة BeginInvokeإلى تحديد عندما تم إكمال الاستدعاء غير متزامن، وقم باستدعاء EndInvoke.

  • تمرير تفويض لأسلوب رد اتصال إلى BeginInvoke. الأسلوب هو تنفيذها تشغيل ThreadPoolمؤشر ترابط عند إكمال الاستدعاء غير متزامن. رد الاتصال أسلوب يستدعي EndInvoke.

ملاحظة هامةهام

بغض النظر عن الأسلوب الذي استخدم، دائماً باستدعاء EndInvokeإلى إكمال استدعاء غير متزامن.

تعريف الأسلوب اختبار وغير متزامنة تفويض

توضح الأمثلة تعليمات برمجية التالية طرق مختلفة للاتصال نفس تشغيلها لفترة طويلة أسلوب، TestMethod، غير متزامن. TestMethodأسلوب عرض رسالة وحدة تحكم إلى المعالجة، لإظهار أنه قد بدأ سكون لبضع ثوان، ثم تنتهي. TestMethodيحتويoutلتوضيح الطريقة التي تتم إضافة هذه المعلمات إلى التواقيع منBeginInvokeوEndInvoke. يمكنك معالجة refالمعلمات بشكل مشابه.

يوضح مثال التعليمة البرمجية التالية التعريف TestMethodوالمفوض باسم AsyncMethodCallerالتي يمكن استخدامها إلى استدعاء TestMethodغير متزامن. إلى ترجمة الأمثلة تعليمات برمجية، يجب عليك تضمين ملفات تعريف ل TestMethodو AsyncMethodCallerالمفوض.

Imports System
Imports System.Threading
Imports System.Runtime.InteropServices 

Namespace Examples.AdvancedProgramming.AsynchronousOperations
    Public Class AsyncDemo 
        ' The method to be executed asynchronously.
        Public Function TestMethod(ByVal callDuration As Integer, _
                <Out> ByRef threadId As Integer) As String
            Console.WriteLine("Test method begins.")
            Thread.Sleep(callDuration)
            threadId = Thread.CurrentThread.ManagedThreadId()
            return String.Format("My call time was {0}.", callDuration.ToString())
        End Function
    End Class

    ' The delegate must have the same signature as the method
    ' it will call asynchronously.
    Public Delegate Function AsyncMethodCaller(ByVal callDuration As Integer, _
        <Out> ByRef threadId As Integer) As String
End Namespace
using System;
using System.Threading; 

namespace Examples.AdvancedProgramming.AsynchronousOperations
{
    public class AsyncDemo 
    {
        // The method to be executed asynchronously.
        public string TestMethod(int callDuration, out int threadId) 
        {
            Console.WriteLine("Test method begins.");
            Thread.Sleep(callDuration);
            threadId = Thread.CurrentThread.ManagedThreadId;
            return String.Format("My call time was {0}.", callDuration.ToString());
        }
    }
    // The delegate must have the same signature as the method
    // it will call asynchronously.
    public delegate string AsyncMethodCaller(int callDuration, out int threadId);
}
using namespace System;
using namespace System::Threading;
using namespace System::Runtime::InteropServices; 

namespace Examples {
namespace AdvancedProgramming {
namespace AsynchronousOperations
{
    public ref class AsyncDemo 
    {
    public:
        // The method to be executed asynchronously.
        String^ TestMethod(int callDuration, [OutAttribute] int% threadId) 
        {
            Console::WriteLine("Test method begins.");
            Thread::Sleep(callDuration);
            threadId = Thread::CurrentThread->ManagedThreadId;
            return String::Format("My call time was {0}.", callDuration);
        }
    };

    // The delegate must have the same signature as the method
    // it will call asynchronously.
    public delegate String^ AsyncMethodCaller(int callDuration, [OutAttribute] int% threadId);
}}}

جارى الإنتظار غير متزامن يتصل مع EndInvoke

أن أبسط طريقة إلى ينفذ أسلوب بشكل غير متزامن هو إلى بدء ينفذ الأسلوب باستدعاء المفوض BeginInvokeالطريقة، قم ببعض العمل تشغيل مؤشر ترابط الرئيسي، وقم باستدعاء المفوض EndInvokeالأسلوب. EndInvokeقد حظر الاتصال مؤشر ترابط نظراً لعدم عودة إلى أن تكتمل الاستدعاء غير متزامن. Th هو هو أسلوب جيد للاستخدام مع العمليات الشبكة أو الملف.

ملاحظة هامةهام

لأن EndInvokeقد منع، يجب عدم الاتصال به من عمليات جزئية تلك الالخدمة واجهة مستخدم.

Imports System
Imports System.Threading
Imports System.Runtime.InteropServices 

Namespace Examples.AdvancedProgramming.AsynchronousOperations
    Public Class AsyncMain 
        Shared Sub Main() 
            ' The asynchronous method puts the thread id here.
            Dim threadId As Integer

            ' Create an instance of the test class.
            Dim ad As New AsyncDemo()

            ' Create the delegate.
            Dim caller As New AsyncMethodCaller(AddressOf ad.TestMethod)

            ' Initiate the asynchronous call.
            Dim result As IAsyncResult = caller.BeginInvoke(3000, _
                threadId, Nothing, Nothing)

            Thread.Sleep(0)
            Console.WriteLine("Main thread {0} does some work.", _
                 Thread.CurrentThread.ManagedThreadId)

            ' Call EndInvoke to Wait for the asynchronous call to complete,
            ' and to retrieve the results.
            Dim returnValue As String = caller.EndInvoke(threadId, result)

            Console.WriteLine("The call executed on thread {0}, with return value ""{1}"".", _
                threadId, returnValue)
        End Sub
    End Class

End Namespace

'This example produces output similar to the following:
'
'Main thread 1 does some work.
'Test method begins.
'The call executed on thread 3, with return value "My call time was 3000.".
using System;
using System.Threading;

namespace Examples.AdvancedProgramming.AsynchronousOperations
{
    public class AsyncMain 
    {
        public static void Main() 
        {
            // The asynchronous method puts the thread id here.
            int threadId;

            // Create an instance of the test class.
            AsyncDemo ad = new AsyncDemo();

            // Create the delegate.
            AsyncMethodCaller caller = new AsyncMethodCaller(ad.TestMethod);

            // Initiate the asychronous call.
            IAsyncResult result = caller.BeginInvoke(3000, 
                out threadId, null, null);

            Thread.Sleep(0);
            Console.WriteLine("Main thread {0} does some work.",
                Thread.CurrentThread.ManagedThreadId);

            // Call EndInvoke to wait for the asynchronous call to complete,
            // and to retrieve the results.
            string returnValue = caller.EndInvoke(out threadId, result);

            Console.WriteLine("The call executed on thread {0}, with return value \"{1}\".",
                threadId, returnValue);
        }
    }
}

/* This example produces output similar to the following:

Main thread 1 does some work.
Test method begins.
The call executed on thread 3, with return value "My call time was 3000.".
 */
#using <TestMethod.dll>

using namespace System;
using namespace System::Threading;
using namespace Examples::AdvancedProgramming::AsynchronousOperations;

void main() 
{
    // The asynchronous method puts the thread id here.
    int threadId = 2546;

    // Create an instance of the test class.
    AsyncDemo^ ad = gcnew AsyncDemo();

    // Create the delegate.
    AsyncMethodCaller^ caller = gcnew AsyncMethodCaller(ad, &AsyncDemo::TestMethod);

    // Initiate the asychronous call.
    IAsyncResult^ result = caller->BeginInvoke(3000, 
        threadId, nullptr, nullptr);

    Thread::Sleep(1);
    Console::WriteLine("Main thread {0} does some work.",
        Thread::CurrentThread->ManagedThreadId);

    // Call EndInvoke to wait for the asynchronous call to complete,
    // and to retrieve the results.
    String^ returnValue = caller->EndInvoke(threadId, result);

    Console::WriteLine("The call executed on thread {0}, with return value \"{1}\".",
        threadId, returnValue);
}

/* This example produces output similar to the following:

Main thread 1 does some work.
Test method begins.
The call executed on thread 3, with return value "My call time was 3000.".
 */

جارى الإنتظار غير متزامن يتصل مع WaitHandle

يمكنك الحصول على WaitHandleباستخدام AsyncWaitHandleخاصية IAsyncResultالتي يتم إرجاعها بواسطة BeginInvoke. WaitHandleهو إليه بصوت عند إكمال الاستدعاء غير متزامن، ويمكنك الانتظار حتى عن طريق استدعاء WaitOneالأسلوب.

إذا استخدمت WaitHandle، يمكنك تنفيذ معالجة إضافى قبل أو بعد إكمال الاستدعاء غير متزامن، ولكن قبل إجراء الاتصال EndInvokeإلى استرداد نتائج.

ملاحظةملاحظة

مؤشر الانتظار هو غير مغلق تلقائياً عندما تقوم باستدعاء EndInvoke.في حالة تحرير الجميع المراجع إلى مؤشر الانتظار، يتم تحرير موارد النظام عند البيانات المهملة مجموعة reclaims المقبض الانتظار.إلى مجانية باستخدام مؤشر الانتظار، التخلص موارد النظام بمجرد الانتهاء منها بواسطة استدعاء WaitHandle.Closeالأسلوب.يعمل تجميع البيانات المهملة بشكل أكثر فعالية عندما يتم التخلص من الكائنات disposable بوضوح.

Imports System
Imports System.Threading
Imports System.Runtime.InteropServices 

Namespace Examples.AdvancedProgramming.AsynchronousOperations

    Public Class AsyncMain 
        Shared Sub Main() 
            ' The asynchronous method puts the thread id here.
            Dim threadId As Integer

            ' Create an instance of the test class.
            Dim ad As New AsyncDemo()

            ' Create the delegate.
            Dim caller As New AsyncMethodCaller(AddressOf ad.TestMethod)

            ' Initiate the asynchronous call.
            Dim result As IAsyncResult = caller.BeginInvoke(3000, _
                threadId, Nothing, Nothing)

            Thread.Sleep(0)
            Console.WriteLine("Main thread {0} does some work.", _
                Thread.CurrentThread.ManagedThreadId)
            ' Perform additional processing here and then
            ' wait for the WaitHandle to be signaled.
            result.AsyncWaitHandle.WaitOne()

            ' Call EndInvoke to retrieve the results.
            Dim returnValue As String = caller.EndInvoke(threadId, result)

            ' Close the wait handle.
            result.AsyncWaitHandle.Close()

            Console.WriteLine("The call executed on thread {0}, with return value ""{1}"".", _
                threadId, returnValue)
        End Sub
    End Class
End Namespace

'This example produces output similar to the following:
'
'Main thread 1 does some work.
'Test method begins.
'The call executed on thread 3, with return value "My call time was 3000.".
using System;
using System.Threading;

namespace Examples.AdvancedProgramming.AsynchronousOperations
{
    public class AsyncMain 
    {
        static void Main() 
        {
            // The asynchronous method puts the thread id here.
            int threadId;

            // Create an instance of the test class.
            AsyncDemo ad = new AsyncDemo();

            // Create the delegate.
            AsyncMethodCaller caller = new AsyncMethodCaller(ad.TestMethod);

            // Initiate the asychronous call.
            IAsyncResult result = caller.BeginInvoke(3000, 
                out threadId, null, null);

            Thread.Sleep(0);
            Console.WriteLine("Main thread {0} does some work.",
                Thread.CurrentThread.ManagedThreadId);

            // Wait for the WaitHandle to become signaled.
            result.AsyncWaitHandle.WaitOne();

            // Perform additional processing here.
            // Call EndInvoke to retrieve the results.
            string returnValue = caller.EndInvoke(out threadId, result);

            // Close the wait handle.
            result.AsyncWaitHandle.Close();

            Console.WriteLine("The call executed on thread {0}, with return value \"{1}\".",
                threadId, returnValue);
        }
    }
}

/* This example produces output similar to the following:

Main thread 1 does some work.
Test method begins.
The call executed on thread 3, with return value "My call time was 3000.".
 */
#using <TestMethod.dll>

using namespace System;
using namespace System::Threading;
using namespace Examples::AdvancedProgramming::AsynchronousOperations;

void main() 
{
    // The asynchronous method puts the thread id here.
    int threadId;

    // Create an instance of the test class.
    AsyncDemo^ ad = gcnew AsyncDemo();

    // Create the delegate.
    AsyncMethodCaller^ caller = gcnew AsyncMethodCaller(ad, &AsyncDemo::TestMethod);

    // Initiate the asychronous call.
    IAsyncResult^ result = caller->BeginInvoke(3000, 
        threadId, nullptr, nullptr);

    Thread::Sleep(0);
    Console::WriteLine("Main thread {0} does some work.",
        Thread::CurrentThread->ManagedThreadId);

    // Wait for the WaitHandle to become signaled.
    result->AsyncWaitHandle->WaitOne();

    // Perform additional processing here.
    // Call EndInvoke to retrieve the results.
    String^ returnValue = caller->EndInvoke(threadId, result);

    // Close the wait handle.
    result->AsyncWaitHandle->Close();

    Console::WriteLine("The call executed on thread {0}, with return value \"{1}\".",
        threadId, returnValue);
}

/* This example produces output similar to the following:

Main thread 1 does some work.
Test method begins.
The call executed on thread 3, with return value "My call time was 3000.".
 */

للاستقصاء عن يتصل إكمال غير متزامن

يمكنك استخدام IsCompletedخاصية IAsyncResultالتي يتم إرجاعها بواسطة BeginInvokeإلى اكتشاف عند إكمال الاستدعاء غير متزامن. قد تقوم بذلك عند إنشاء غير متزامن يتصل من مؤشر ترابط الخدمات واجهة مستخدم. الاستقصاء عن إتمام يسمح مؤشر ترابط استدعاء إلى متابعة تنفيذ أثناء تنفيذ الاستدعاء غير متزامن تشغيل ThreadPoolمؤشر ترابط.

Imports System
Imports System.Threading
Imports System.Runtime.InteropServices 

Namespace Examples.AdvancedProgramming.AsynchronousOperations

    Public Class AsyncMain 
        Shared Sub Main() 
            ' The asynchronous method puts the thread id here.
            Dim threadId As Integer

            ' Create an instance of the test class.
            Dim ad As New AsyncDemo()

            ' Create the delegate.
            Dim caller As New AsyncMethodCaller(AddressOf ad.TestMethod)

            ' Initiate the asynchronous call.
            Dim result As IAsyncResult = caller.BeginInvoke(3000, _
                threadId, Nothing, Nothing)

            ' Poll while simulating work.
            While result.IsCompleted = False
                Thread.Sleep(250)
                Console.Write(".")
            End While

            ' Call EndInvoke to retrieve the results.
            Dim returnValue As String = caller.EndInvoke(threadId, result)

            Console.WriteLine(vbCrLf & _
                "The call executed on thread {0}, with return value ""{1}"".", _
                threadId, returnValue)
        End Sub
    End Class
End Namespace

' This example produces output similar to the following:
'
'Test method begins.
'.............
'The call executed on thread 3, with return value "My call time was 3000.".
using System;
using System.Threading;

namespace Examples.AdvancedProgramming.AsynchronousOperations
{
    public class AsyncMain 
    {
        static void Main() {
            // The asynchronous method puts the thread id here.
            int threadId;

            // Create an instance of the test class.
            AsyncDemo ad = new AsyncDemo();

            // Create the delegate.
            AsyncMethodCaller caller = new AsyncMethodCaller(ad.TestMethod);

            // Initiate the asychronous call.
            IAsyncResult result = caller.BeginInvoke(3000, 
                out threadId, null, null);

            // Poll while simulating work.
            while(result.IsCompleted == false) {
                Thread.Sleep(250);
                Console.Write(".");
            }

            // Call EndInvoke to retrieve the results.
            string returnValue = caller.EndInvoke(out threadId, result);

            Console.WriteLine("\nThe call executed on thread {0}, with return value \"{1}\".",
                threadId, returnValue);
        }
    }
}

/* This example produces output similar to the following:

Test method begins.
.............
The call executed on thread 3, with return value "My call time was 3000.".
 */
#using <TestMethod.dll>

using namespace System;
using namespace System::Threading;
using namespace Examples::AdvancedProgramming::AsynchronousOperations;

void main() 
{
    // The asynchronous method puts the thread id here.
    int threadId;

    // Create an instance of the test class.
    AsyncDemo^ ad = gcnew AsyncDemo();

    // Create the delegate.
    AsyncMethodCaller^ caller = gcnew AsyncMethodCaller(ad, &AsyncDemo::TestMethod);

    // Initiate the asychronous call.
    IAsyncResult^ result = caller->BeginInvoke(3000, 
        threadId, nullptr, nullptr);

    // Poll while simulating work.
    while(result->IsCompleted == false)
    {
        Thread::Sleep(250);
        Console::Write(".");
    }

    // Call EndInvoke to retrieve the results.
    String^ returnValue = caller->EndInvoke(threadId, result);

    Console::WriteLine("\nThe call executed on thread {0}, with return value \"{1}\".",
        threadId, returnValue);
}

/* This example produces output similar to the following:

Test method begins.
.............
The call executed on thread 3, with return value "My call time was 3000.".
 */

تنفيذ يتصل خلف أسلوب عند غير متزامن يتصل Completes

لا يلزم أن يكون مؤشر ترابط الذي يعالج نتائج مؤشر ترابط الذي يبدأ الاستدعاء غير متزامن، يمكن ينفذ أسلوب رد اتصال عند إتمام المكالمة. يتم تنفيذ أسلوب رد الاتصال تشغيل ThreadPoolمؤشر ترابط.

إلى استخدم a callback أسلوب, you must pass BeginInvoke an AsyncCallback تفويض that represents the callback أسلوب. You can also pass an كائن that يحتوي على معلومات إلى be used بواسطة the callback أسلوب. في the callback أسلوب, you can cast the IAsyncResult, which هو the فقط معلمة of the callback أسلوب, إلى an AsyncResult كائن. You can then استخدم the AsyncResult.AsyncDelegate خاصية إلى يحصل the تفويض that was used إلى initiate the يتصل so that you can يتصل EndInvoke.

ملاحظات تشغيل the مثال:

  • The threadId parameter of TestMethod is an out parameter (<Out> ByRef in Visual Basic), so its input value is never used by TestMethod. متغير وهمية هو التي تم تمريرها إلى BeginInvokeالمكالمة. إذا threadIdكانت معلمة refمعلمة ( ByRefفي Visual أساسى)، سيضطر المتغير أن فئة-المستوى الحقل حيث أنه قد يتم تمريرها إلى كلا BeginInvokeو EndInvoke.

  • الولاية المعلومات التي يتم تمريرها إلى BeginInvokeهو سلسلة تنسيق، والذي يستخدم الأسلوب رد الاتصال لتنسيق عنصر رسالة الإخراج. لأن ذلك هو التي تم تمريرها الكتابة Object، يجب أن يتم تحويل المعلومات الحالة بنوعه الصحيح قبل استخدامه.

  • رد الاتصال هو التي تم إجراؤها تشغيل ThreadPoolمؤشر ترابط. ThreadPoolهي عمليات جزئية لمؤشرات ترابط الخلفية، لا الاحتفاظ تشغيل تطبيق في حالة إنهاء مؤشر ترابط الرئيسي، بحيث مؤشر ترابط الرئيسي من مثال إلى حالة سكون طويل كفاية لرد الاتصال للانتهاء.

Imports System
Imports System.Threading
Imports System.Runtime.Remoting.Messaging

Namespace Examples.AdvancedProgramming.AsynchronousOperations

    Public Class AsyncMain 

        Shared Sub Main() 

            ' Create an instance of the test class.
            Dim ad As New AsyncDemo()

            ' Create the delegate.
            Dim caller As New AsyncMethodCaller(AddressOf ad.TestMethod)

            ' The threadId parameter of TestMethod is an <Out> parameter, so
            ' its input value is never used by TestMethod. Therefore, a dummy
            ' variable can be passed to the BeginInvoke call. If the threadId
            ' parameter were a ByRef parameter, it would have to be a class-
            ' level field so that it could be passed to both BeginInvoke and 
            ' EndInvoke.
            Dim dummy As Integer = 0

            ' Initiate the asynchronous call, passing three seconds (3000 ms)
            ' for the callDuration parameter of TestMethod; a dummy variable 
            ' for the <Out> parameter (threadId); the callback delegate; and
            ' state information that can be retrieved by the callback method.
            ' In this case, the state information is a string that can be used
            ' to format a console message.
            Dim result As IAsyncResult = caller.BeginInvoke(3000, _
                dummy, _
                AddressOf CallbackMethod, _
                "The call executed on thread {0}, with return value ""{1}"".")

            Console.WriteLine("The main thread {0} continues to execute...", _
                Thread.CurrentThread.ManagedThreadId)

            ' The callback is made on a ThreadPool thread. ThreadPool threads
            ' are background threads, which do not keep the application running
            ' if the main thread ends. Comment out the next line to demonstrate
            ' this.
            Thread.Sleep(4000)

            Console.WriteLine("The main thread ends.")
        End Sub

        ' The callback method must have the same signature as the
        ' AsyncCallback delegate.
        Shared Sub CallbackMethod(ByVal ar As IAsyncResult)
            ' Retrieve the delegate.
            Dim result As AsyncResult = CType(ar, AsyncResult)
            Dim caller As AsyncMethodCaller = CType(result.AsyncDelegate, AsyncMethodCaller)

            ' Retrieve the format string that was passed as state 
            ' information.
            Dim formatString As String = CType(ar.AsyncState, String)

            ' Define a variable to receive the value of the <Out> parameter.
            ' If the parameter were ByRef rather than <Out> then it would have to
            ' be a class-level field so it could also be passed to BeginInvoke.
            Dim threadId As Integer = 0

            ' Call EndInvoke to retrieve the results.
            Dim returnValue As String = caller.EndInvoke(threadId, ar)

            ' Use the format string to format the output message.
            Console.WriteLine(formatString, threadId, returnValue)
        End Sub
    End Class
End Namespace

' This example produces output similar to the following:
'
'The main thread 1 continues to execute...
'Test method begins.
'The call executed on thread 3, with return value "My call time was 3000.".
'The main thread ends.
using System;
using System.Threading;
using System.Runtime.Remoting.Messaging;

namespace Examples.AdvancedProgramming.AsynchronousOperations
{
    public class AsyncMain 
    {
        static void Main() 
        {
            // Create an instance of the test class.
            AsyncDemo ad = new AsyncDemo();

            // Create the delegate.
            AsyncMethodCaller caller = new AsyncMethodCaller(ad.TestMethod);

            // The threadId parameter of TestMethod is an out parameter, so
            // its input value is never used by TestMethod. Therefore, a dummy
            // variable can be passed to the BeginInvoke call. If the threadId
            // parameter were a ref parameter, it would have to be a class-
            // level field so that it could be passed to both BeginInvoke and 
            // EndInvoke.
            int dummy = 0;

            // Initiate the asynchronous call, passing three seconds (3000 ms)
            // for the callDuration parameter of TestMethod; a dummy variable 
            // for the out parameter (threadId); the callback delegate; and
            // state information that can be retrieved by the callback method.
            // In this case, the state information is a string that can be used
            // to format a console message.
            IAsyncResult result = caller.BeginInvoke(3000,
                out dummy, 
                new AsyncCallback(CallbackMethod),
                "The call executed on thread {0}, with return value \"{1}\".");

            Console.WriteLine("The main thread {0} continues to execute...", 
                Thread.CurrentThread.ManagedThreadId);

            // The callback is made on a ThreadPool thread. ThreadPool threads
            // are background threads, which do not keep the application running
            // if the main thread ends. Comment out the next line to demonstrate
            // this.
            Thread.Sleep(4000);

            Console.WriteLine("The main thread ends.");
        }

        // The callback method must have the same signature as the
        // AsyncCallback delegate.
        static void CallbackMethod(IAsyncResult ar) 
        {
            // Retrieve the delegate.
            AsyncResult result = (AsyncResult) ar;
            AsyncMethodCaller caller = (AsyncMethodCaller) result.AsyncDelegate;

            // Retrieve the format string that was passed as state 
            // information.
            string formatString = (string) ar.AsyncState;

            // Define a variable to receive the value of the out parameter.
            // If the parameter were ref rather than out then it would have to
            // be a class-level field so it could also be passed to BeginInvoke.
            int threadId = 0;

            // Call EndInvoke to retrieve the results.
            string returnValue = caller.EndInvoke(out threadId, ar);

            // Use the format string to format the output message.
            Console.WriteLine(formatString, threadId, returnValue);
        }
    }
}

/* This example produces output similar to the following:

The main thread 1 continues to execute...
Test method begins.
The call executed on thread 3, with return value "My call time was 3000.".
The main thread ends.
 */
#using <TestMethod.dll>

using namespace System;
using namespace System::Threading;
using namespace System::Runtime::Remoting::Messaging;
using namespace Examples::AdvancedProgramming::AsynchronousOperations;

// The callback method must have the same signature as the
// AsyncCallback delegate.
void CallbackMethod(IAsyncResult^ ar) 
{
    // Retrieve the delegate.
    AsyncResult^ result = (AsyncResult^) ar;
    AsyncMethodCaller^ caller = (AsyncMethodCaller^) result->AsyncDelegate;

    // Retrieve the format string that was passed as state 
    // information.
    String^ formatString = (String^) ar->AsyncState;

    // Define a variable to receive the value of the out parameter.
    // If the parameter were ref rather than out then it would have to
    // be a class-level field so it could also be passed to BeginInvoke.
    int threadId = 0;

    // Call EndInvoke to retrieve the results.
    String^ returnValue = caller->EndInvoke(threadId, ar);

    // Use the format string to format the output message.
    Console::WriteLine(formatString, threadId, returnValue);
};

void main() 
{
    // Create an instance of the test class.
    AsyncDemo^ ad = gcnew AsyncDemo();

    // Create the delegate.
    AsyncMethodCaller^ caller = gcnew AsyncMethodCaller(ad, &AsyncDemo::TestMethod);

    // The threadId parameter of TestMethod is an out parameter, so
    // its input value is never used by TestMethod. Therefore, a dummy
    // variable can be passed to the BeginInvoke call. If the threadId
    // parameter were a ref parameter, it would have to be a class-
    // level field so that it could be passed to both BeginInvoke and 
    // EndInvoke.
    int dummy = 0;

    // Initiate the asynchronous call, passing three seconds (3000 ms)
    // for the callDuration parameter of TestMethod; a dummy variable 
    // for the out parameter (threadId); the callback delegate; and
    // state information that can be retrieved by the callback method.
    // In this case, the state information is a string that can be used
    // to format a console message.
    IAsyncResult^ result = caller->BeginInvoke(3000,
        dummy, 
        gcnew AsyncCallback(&CallbackMethod),
        "The call executed on thread {0}, with return value \"{1}\".");

    Console::WriteLine("The main thread {0} continues to execute...", 
        Thread::CurrentThread->ManagedThreadId);

    // The callback is made on a ThreadPool thread. ThreadPool threads
    // are background threads, which do not keep the application running
    // if the main thread ends. Comment out the next line to demonstrate
    // this.
    Thread::Sleep(4000);
    Console::WriteLine("The main thread ends.");
}

/* This example produces output similar to the following:

The main thread 1 continues to execute...
Test method begins.
The call executed on thread 3, with return value "My call time was 3000.".
The main thread ends.
 */

راجع أيضًا:

المرجع

Delegate

موارد أخرى

غير متزامن برمجة تصميم نقوش