سؤال

أنا عموما الحذر من تنفيذ واجهات جزئيا.ومع ذلك ، IAsyncResult هو جزء من حالة خاصة ، بالنظر إلى أنه يدعم عدة مختلفة تماما أنماط الاستخدام.كيف وغالبا ما كنت تستخدم/شاهد تستخدم AsyncState/AsyncCallback نمط بدلا من مجرد الدعوة EndInvoke, باستخدام AsyncWaitHandle, أو الاقتراع IsCompleted (يع)?

ذات السؤال: كشف أن ThreadPool WorkItem أكملت/في انتظار الانتهاء.

النظر في هذه الفئة (تقريبية جدا ، وتأمين الحاجة):

public class Concurrent<T> {
    private ManualResetEvent _resetEvent;
    private T _result;

    public Concurrent(Func<T> f) {
        ThreadPool.QueueUserWorkItem(_ => {
                                         _result = f();
                                         IsCompleted = true;
                                         if (_resetEvent != null)
                                             _resetEvent.Set();
                                     });
    }

    public WaitHandle WaitHandle {
        get {
            if (_resetEvent == null)
                _resetEvent = new ManualResetEvent(IsCompleted);
            return _resetEvent;
        }

    public bool IsCompleted {get; private set;}
    ...

وقد WaitHandle (بتكاسل خلقت فقط كما هو موضح في IAsyncResult وثائق) ، IsCompleted, ولكن لا أرى من المعقول تنفيذ AsyncState ({return null;}?).لذلك لا معنى أن تنفيذ IAsyncResult?علما بأن Task في موازاة مكتبة ملحقات لا تنفذ IAsyncResult, ولكن فقط IsCompleted يتم تنفيذ ضمنا.

هل كانت مفيدة؟

المحلول

  • في تجربتي, فقط اتصل EndInvoke دون أي انتظار أو استدعائه مرة أخرى أولا نادرا ما تكون مفيدة
  • مجرد تقديم رد في بعض الأحيان لا يكفي ، للعملاء الخاص بك قد تحتاج إلى الانتظار لعدة عمليات في وقت واحد (WaitAny, WaitAll)
  • لم شملهم الاستطلاع IsCompleted ، يع في الواقع!لذا, هل يمكن حفظ تنفيذ IsCompleted, لكنه بسيط جدا أنه لا يبدو أن تكون قيمتها قد يدهش العملاء.

لذا معقول التنفيذ لمدة بشكل غير متزامن للاستدعاء الطريقة يجب توفر حقا بالكامل IAsyncResult.

راجع للشغل, كنت في كثير من الأحيان لا تحتاج إلى تنفيذ IAsyncResult نفسك ، والعودة فقط ما يتم إرجاعها بواسطة مندوب.BeginInvoke.انظر تنفيذ النظام.IO.تيار.BeginRead على سبيل المثال.

نصائح أخرى

يبدو أن لديك بعض الأسئلة.دعونا التعامل معها بشكل فردي

خلق WaitHandle بتكاسل

نعم هذا هو النهج الأكثر الصحيح.يتعين عليك أن تفعل هذا في موضوع بطريقة آمنة ولكن كسول هو الطريق.

خدعة على الرغم من التخلص من WaitHandle.WaitHandle قاعدة IDisposable ، يجب أن يتم التخلص منها في الوقت المناسب.وثائق IAsycResult لا تغطي هذه الحالة.أفضل طريقة للقيام بذلك هو في EndInvoke.وثائق BeginInvoke صراحة على أن لكل BeginInvoke ، يجب أن يكون هناك مقابلة EndInvoke (أو BeginRead/EndRead).هذا هو أفضل مكان للتخلص من WaitHandle.

كيف ينبغي أن AsyncState أن تنفذ ؟

إذا نظرتم إلى مستوى BCL API التي يعود IAsyncResult معظمهم تأخذ الدولة المعلمة.عادة هذا هو القيمة التي تم إرجاعها من AsyncState (انظر مأخذ API للحصول على مثال).وهو ممارسة جيدة أن تدرج الدولة متغير كتابة كائن أي API BeginInvoke نمط API التي بإرجاع IAsyncResult.ليس من الضروري ولكن الممارسة الجيدة.

في abscence الدولة متغير ، والعودة فارغة مقبول.

IsCompleted API

هذا سوف تعتمد إلى حد كبير على تنفيذ مما يخلق IAsyncResult.ولكن نعم ، يجب عليك تنفيذها.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top