تنظيم الاستجواب ، المهلات

أقوم بتطوير تطبيق يعمل مع 8 منافذ COM ، عندما يتم استلام البيانات من أحد منافذ COM ، يتم استدعاء معالج الحدث ، يقوم التطبيق بإنشاء غلاف للرسالة المستلمة عبر منفذ COM ، ويرسلها عبر TCP إلى المضيف البعيد. في الواقع بعد الالتفاف ، يصبح الأمر جهازًا في مكان ما في شبكة تستند إلى ethernet (بدء قياس الأمر).

أنا باستخدام SerialPort و SerialDataReceivedEventHandler للعمل مع منافذ COM. المشكلة هي أن لدي مهلة (0-1000 مللي ثانية) المحددة بشكل مختلف لكل منفذ COM عبر النموذج. بعد هذه المهلة ، يجب إرسال أمر آخر للحصول على بعض البيانات من الجهاز (الحصول على أمر البيانات).

  • هذا الأمر مختلف لكل 8 منافذ COM
  • يجب إرسال هذا الأمر فقط بعد استلام البيانات عبر منفذ COM وإرسال الأمر الأول
  • يختلف
  • المهلة بين أمرين لكل منفذ com

هل لديك أي اقتراحات حول تنظيم المهلة؟ شكر.

لدي فكرة واحدة ، لكنني لست متأكدًا مما إذا كان ذلك ممكنًا: لدي 8 وظائف معالج الأحداث لكل منفذ COM.

...something
sendFirstCommand();
Thread.Sleep(comPortNTimeout);
sendSecondCommand();

هل يمكنني استخدام نفس البناء في كل واحد منهم؟ يتم تجميد معالج Won't المنفذ الأول إذا كان سيتم استدعاء البيانات Thread.Sleep() في معالج المنفذ الثاني على سبيل المثال؟

3

1 إجابة

1) تقديم نوع من فئة CommandSourceContext التي تلخص جميع المعلمات المتعلقة بكل منفذ COM (انظر أدناه)

2) لمعرفة ما إذا كان سيتم تجميد معالجات أثناء رفع حدث منفذ آخر - فقط اختباره في مصحح الأخطاء ومعرفة ما إذا تم استدعاء كافة أحداث المنفذ في نفس مؤشر الترابط. يمكنك استخدام إطار Visual Studio 2010 مؤشرات الترابط ، فقط ضع نقطة فاصل في معالج الأحداث منفذ COM وانظر ما هو معرف مؤشر الترابط الحالي. إذا كنت تستخدم Visual Studio أقدم - فقط سجل معرف مؤشر الترابط الوصول إليه عبر Thread.CurrentThread.ManagedThreadId . لذلك إذا تم استدعاء الأحداث من منافذ مختلفة في نفس الخيط - من الواضح أن معالجات كل منها ، وإلا سيتم تشغيلها بالتوازي منذ استدعائها في مواضيع مختلفة. يقول MSDN على الأقل (انظر في أسفل هذه الإجابة) أن البيانات التي يتم تلقيها الأحداث لا تثار في الخيط الرئيسي ، لذا يجب عليك توخي الحذر عند الوصول إلى عناصر واجهة تعامل المستخدم.

interface ICommandSourceContext
{
  //Since each port has own specific command
  //we can encapsulate it in the context as well
   ICommand Command { get; }

   int PortNumber { get; }
   long TimeIntervalMilliseconds { get; }
   Action Callback { get; }     
}

// setup and add all contexts
IList contexts = new List();

// ideally your main code block should looks like below (this is only pseudo code)
foreach (var context in contexts)
{
  //to execute it asyncronously you can use TPL Task.Start()
  //so it would not block other handlers in case of single thread
   context.Command.Execute();
   Thread.Sleep(context.TimeIntervalMilliseconds);
}

SerialPort.DataReceived Event remarks:

يتم رفع الحدث DataReceived على مؤشر ترابط ثانوي عند وجود البيانات   تلقي من كائن SerialPort. لأن هذا الحدث مرفوع على   الخيط الثانوي ، وليس موضوع الرئيسي ، في محاولة لتعديل بعض   عناصر في الموضوع الرئيسي ، مثل عناصر واجهة المستخدم ، يمكن أن يرفع أ   استثناء مؤشر الترابط. إذا كان من الضروري تعديل العناصر في الرئيسي   نموذج أو التحكم ، طلبات التغيير مرة أخرى باستخدام Invoke ، والتي ستفعل   العمل على موضوع المناسبة

2
وأضاف
شكرًا لك ، إنها وظيفة رائعة ومفيدة حقًا. لسوء الحظ ، لا توجد فرصة للحصول على منفذ تسلسلي إضافي واحد على الأقل لمحطة العمل الخاصة بي. لن أتمكن إلا من اختبار هذه المشكلة في المستقبل.
وأضاف المؤلف vard, مصدر
يمكنك إنشاء أداة اختبار لطيفة لمحاكاة منافذ متعددة والتأكد من أن التنفيذ الخاص بك يعمل بشكل جيد ، وهذا من شأنه أن يعمل من أجلك على المدى الطويل أيضًا
وأضاف المؤلف sll, مصدر
في الواقع، إذا كان لي 8 أجهزة منفذ COM لمثل هذا الطلب، وأود أن استخدام واحدة من هذه RS232 إلى أجهزة إيثرنت بحيث SW الخاص بك يمكن أن تتعامل مباشرة مع إيثرنت ولا تعبث مع المنافذ التسلسلية على الإطلاق. perle.com/products/&hellip؛</و>
وأضاف المؤلف TJD, مصدر