المنفذ التسلسلي والمناولة الأخطاء أثناء عمليات الإدخال / الإخراج المتداخلة

StackOverflow https://stackoverflow.com/questions/1316132

سؤال

لقد قمت بعمل الاتصالات التسلسلية مؤخرا حتى أعدت فئة كونها واجهة بسيطة لجميع وظائف واجهة برمجة تطبيقات Windows المسؤولة عن القراءة والكتابة وما إلى ذلك. يتم التعامل مع جميع عمليات الإدخال / الإخراج داخل هذه الفئة بطريقة غير متزاملة.

قبل أن أذهب إلى سؤالي، اسمحوا لي أن أظهر لك كيف أكتب وقراءة البيانات من المنفذ التسلسلي (هذه هي وظيفة القراءة فقط، لأن هيكل الكتابة هو نفسه بالضبط لذلك لا توجد نقطة في تقديم كل منهما) وبعد

function TSerialPort.Read(var pBuffer; const lBufferSize: Cardinal): Cardinal;
var
  lOverlapped: OVERLAPPED;
  lLastError: Cardinal;
  lEvent: TEvent;
begin
  lEvent := TEvent.Create(nil, True, False, '');
  try
    FillChar(lOverlapped, SizeOf(lOverlapped), 0);
    lOverlapped.hEvent := lEvent.Handle;

    if not ReadFile(FSerialPortHandle, pBuffer, lBufferSize, Result, @lOverlapped) then
    begin
      lLastError := GetLastError;
      if (lLastError <> ERROR_IO_PENDING) and (lLastError <> ERROR_SUCCESS) then
        raise Exception.Create(SysErrorMessage(lLastError));

      case lEvent.WaitFor(INFINITE) of
        wrSignaled:
          if not GetOverlappedResult(FSerialPortHandle, lOverlapped, Result, False) then
            raise Exception.Create(SysErrorMessage(GetLastError));

        wrError:
          begin
            lLastError := lEvent.LastError;
            //this is a call to Windows.CancelIo(FSerialPortHandle);
            if Self.CancelIO() then
              lEvent.WaitFor(INFINITE);
            raise Exception.Create(SysErrorMessage(lLastError));
          end;
      end;
    end;
  finally
    FreeAndNil(lEvent);
  end;
end;

قبل أن تسألني لماذا أفتح المنفذ التسلسلي للعمليات المتداخلة بينما تنتظر هذه الوظيفة عملية القراءة حتى النهاية، إليك تفسيري - فقط عند فتح المنفذ التسلسلي بهذه الطريقة يمكنني تحديد طريقة تنتظر الوقت الانتظار () في انتظار الأحداث. إذا فتحت المنفذ للعمليات غير المتداخلة، فستمنح waitcommevent () حتى يظهر حدثا على المنفذ التسلسلي الذي لا يمكن أن يحدث دائما مما يؤدي إلى حظر مؤشر ترابط الاتصال إلى الأبد.

ومع ذلك، دعونا نركز على وظيفة القراءة أعلاه ().

1) أولا وقبل كل شيء، أنتظر دون تحديد أي مهلة زمنية للحدث. هل هناك احتمال أن يمنع الخيط الحالي إلى الأبد لسبب ما بسبب ذلك؟ لا أعرف ما إذا كان بإمكاني أن أكون متأكدا بنسبة 100٪ من أن الحدث سوف يتم تعيينه في وقت أقرب أو في وقت لاحق بواسطة مؤشر الترابط الذي يؤدي عملية القراءة بشكل غير متزامن. أعلم أنه عندما يتم تعيين جميع مهلات قراءة المنفذ التسلسلي إلى الصفر، لن تنتهي عملية القراءة حتى يتم قراءة عدد معين من بايت، ولكن هذا سلوك أدرك ذلك. مسؤولي تتعلق بحالات غير متوقعة التي من شأنها أن تسبب الحدث لا يتم تعيينه أبدا وطريقة الانتظار () للانتظار إلى الأبد - هل من المحتمل أن يحدث؟

2) Waitfor () قد تعرج RETRROR الذي يبلغ أنه حدث بعض الخطأ أثناء عملية الانتظار (ولكن هذا غير مرتبط بعملية القراءة المتداخلة على الإطلاق، أليس كذلك؟). لذلك أعتقد أنني لا ينبغي أن ننتظر عملية القراءة حتى النهاية، لأن مقبض الحدث قد لم يعد قابلا للاستخدام، أليس كذلك؟ لذلك يمكنني استدعاء الأسلوب Cancelio () لإلغاء عملية القراءة، انتظر حتى يتم تعيين الحدث من خلال مؤشر ترابط أداء القراءة الملغاة بشكل غير متزامن بشكل غير متزامن، ثم رفع استثناء. أنتظر حتى يتم إلغاء القراءة من خلال هذا الموضوع لأنه إذا تركت طريقة القراءة الخاصة بي على الفور (دون إلغاء الإدخال / الإخراج)، أود أن أؤدي إلى كتابة موضوع بياناتها (بيانات السجل المتداخلة) إلى المتغيرات المحلية التي من شأنها لم تعد صالحة بعد ذلك، أليس كذلك؟ من ناحية أخرى، هل هناك خطر أن يتم حظر الخيط الحالي إلى الأبد بسبب مكالمة Waitfor (Infinite) قبل زيادة الاستثناء؟

سأكون ممتنا لو تخبرني ما إذا كانت العبارات المذكورة أعلاه صحيحة أو لا تعلق عليها، من فضلك.

شكرا جزيلا لك مقدما.

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

المحلول

فقط من الفضول: لماذا لا تستخدم مكون تسلسلي موجود؟

أنا أستعمل Tubbopower Async. لاستقبال رسائل GPS، ولكن هناك الكثير من الآخرين متاحين بحرية: http://www.efg2.com/lab/library/delphi/io/portio.htm.

يتيح لك معظم هؤلاء القيام بالتواصل التسلسلي على مستوى أعلى بكثير، ويمجد كل مستوى أقل من IO وخيط الخيوط بالنسبة لك.

بهذه الطريقة عليك فقط كتابة onreceive معالج لتلقي، والاتصال send() لإرسال الاشياء.

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