سؤال

أنا أستخدم أ TcpClient في أحد تطبيقاتي Compact Framework 2.0.أريد تلقي بعض المعلومات من خادم TCP.

نظرًا لأن Compact Framework لا يدعم آليات المهلة الخاصة بإطار العمل "الكبير"، فأنا أحاول تنفيذ أمر المهلة الخاص بي.في الأساس، أريد أن أفعل ما يلي:

IAsyncResult result = networkStream.BeginRead(buffer, 0, size, ..., networkStream);
if (!result.AsyncWaitHandle.WaitOne(5000, false))
  // Handle timeout


private void ReceiveFinished(IAsyncResult ar)
{
  NetworkStream stream = (NetworkStream)ar.AsyncState;
  int numBytes = stream.EndRead(ar);

  // SIGNAL IASYNCRESULT.ASYNCWAITHANDLE HERE ... HOW??
}

أود الاتصال Set ل IAsyncResult.AsyncWaitHandle, ، لكن ليس لديها مثل هذه الطريقة ولا أعرف أي تطبيق سأرسله إليه.

كيف أقوم بضبط مقبض الانتظار؟أم أنه يتم ضبطه تلقائيًا عن طريق الاتصال EndRead؟تشير الوثائق إلى أنه يجب علي الاتصال Set نفسي...

شكرا على اي مساعدة!

تحديث
يبدو أن مقبض الانتظار يتم ضبطه تلقائيًا عند الاتصال EndRead - لكنه ليس في المستندات.هل يمكن لأحد أن يؤكد هذا؟

تحديث 2
كتب client.BeginRead في نموذج التعليمات البرمجية الخاص بي.بالطبع، BeginRead ويسمى على NetworkStream...

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

المحلول

أعتقد أن لديك سوء فهم حول عدم مزامنة الإدخال والإخراج مع TCP.

لبدء عملية الإدخال والإخراج غير المتزامنة، اتصل بـstream.BeginRead().
في رد الاتصال، يمكنك استدعاء EndRead على الدفق.

لا يمكنك استدعاء BeginRead على TcpClient، كما يظهر في التعليمات البرمجية الخاصة بك.لا يشير تطبيقك مطلقًا إلى WaitHandle.سوف تستدعي طبقة الإدخال والإخراج رد الاتصال الخاص بك عندما يتم الإشارة إلى مقبض الانتظار، وبعبارة أخرى عندما تحدث القراءة غير المتزامنة.

في رد الاتصال الخاص بك، عادةً ما تقوم بالاتصال بـ BeginRead مرة أخرى، على الدفق، إذا كان من الممكن أن تتلقى المزيد من البيانات.

يمكنك رؤية مثال واضح في هذه الإجابة.

قبل البدء في رقصة BeginRead/Endread ، قد ترغب في إجراء اتصال غير متزامن على tcpclient - ثم يمكنك استخدام Beginconnect.ولكن يتم ذلك مرة واحدة فقط.وبدلاً من ذلك، قد ترغب في اتصال متزامن، وفي هذه الحالة ما عليك سوى الاتصال بـ TcpClient.Connect().

رمز المثال:

    private class AsyncState
    {
        public NetworkStream ns;
        public ManualResetEvent e;
        public byte[] b;
    }

    public void Run()
    {
        NetworkStream networkStream = ...;
        byte[] buffer = new byte[1024];

        var completedEvent = new ManualResetEvent(false);

        networkStream.BeginRead(buffer, 0, buffer.Length,
                                AsyncRead,
                                new AsyncState
                                {
                                    b = buffer,
                                    ns = networkStream,
                                    e = completedEvent
                                });

        // do other stuff here. ...

        // finally, wait for the reading to complete
        completedEvent.WaitOne();
    }


    private void AsyncRead(IAsyncResult ar)
    {
        AsyncState state = ar as AsyncState;
        int n = state.ns.EndRead(ar);
        if (n == 0)
        {
            // signal completion
            state.e.Set();
            return;
        }

        // state.buffer now contains the bytes read
        // do something with it here...
        // for example, dump it into a filesystem file. 

        // read again
        state.ns.BeginRead(state.b, 0, state.b.Length, AsyncRead, state);
    }
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top