visual - مشاريع c#




كيفية القيام قوية البرمجة سيريالبورت مع. نيت/C#؟ (6)

أعتقد أنني قد وصلنا إلى استنتاج أن هايبرترمينال لا يلعب بشكل جيد. لقد أجريت الاختبار التالي:

  1. بدء خدمتي في "وضع وحدة التحكم"، ويبدأ تبديل الجهاز على / قبالة (أستطيع أن أقول من قبل انها ليد).

  2. بدء هيبرترمينال والاتصال بالمنفذ. يبقى الجهاز على (هيبرترمينال يثير دتر) تكتب خدمتي إلى سجل الأحداث، وأنه لا يمكن فتح المنفذ

  3. إيقاف هيبرترمينال، تحقق من أنه مغلق بشكل صحيح باستخدام إدارة المهام

  4. يبقى الجهاز قبالة (هبرترمينال خفضت دتر)، بلدي التطبيق يحتفظ الكتابة إلى سجل الأحداث، قائلا أنه لا يمكن فتح المنفذ.

  5. أبدأ تطبيق ثالث (واحد أحتاج إلى التعايش مع)، وأقول ذلك للاتصال بالمنفذ. أنا أفعل ذلك. لا توجد أخطاء هنا.

  6. أوقف التطبيق المذكور أعلاه.

  7. فويلا، ركلات الخدمة بلدي في مرة أخرى، يفتح الميناء بنجاح، و ليد يذهب أون / أوف.

أنا أكتب خدمة ويندوز للاتصال مع المسلسل ماج الشريط القارئ ومجلس تتابع (نظام التحكم في الوصول).

واجهت مشاكل حيث توقف رمز العمل (أحصل على إوكسيبتيونس) بعد برنامج آخر قد "توقف" العملية عن طريق فتح نفس المنفذ التسلسلي كما خدمتي.

جزء من الشفرة هو كما يلي:

public partial class Service : ServiceBase
{
    Thread threadDoorOpener;
    public Service()
    {
        threadDoorOpener = new Thread(DoorOpener);
    }
    public void DoorOpener()
    {
        while (true)
        {
            SerialPort serialPort = new SerialPort();
            Thread.Sleep(1000);
            string[] ports = SerialPort.GetPortNames();
            serialPort.PortName = "COM1";
            serialPort.BaudRate = 9600;
            serialPort.DataBits = 8;
            serialPort.StopBits = StopBits.One;
            serialPort.Parity = Parity.None;
            if (serialPort.IsOpen) serialPort.Close();
            serialPort.Open();
            serialPort.DtrEnable = true;
            Thread.Sleep(1000);
            serialPort.Close();
        }
    }
    public void DoStart()
    {
        threadDoorOpener.Start();
    }
    public void DoStop()
    {
        threadDoorOpener.Abort();
    }
    protected override void OnStart(string[] args)
    {
        DoStart();
    }
    protected override void OnStop()
    {
        DoStop();
    }
}

برنامج عينة بلدي يبدأ بنجاح مؤشر الترابط العمل، وفتح / إغلاق ورفع دتر يسبب بلدي شريط شريط ماج إلى السلطة حتى (1sec الانتظار)، إيقاف (الانتظار 1 ثانية) وهلم جرا.

إذا قمت بتشغيل هيبرترمينال ويصل إلى منفذ كوم نفسه، هيبرترمينال يقول لي المنفذ قيد الاستخدام حاليا. إذا كنت اضغط مرارا وتكرارا إنتر في هيبرترمينال، في محاولة لإعادة فتح المنفذ سوف تنجح بعد بضع محاولات.

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

برامج أخرى (التي لا تستخدم مكتبات نيت للوصول إلى منفذ) يبدو أن تعمل بشكل طبيعي في هذه المرحلة.

أي أفكار حول ما يسبب هذا؟


لا يمكنك إغلاق اتصال إلسيس شخص ما إلى منفذ، التعليمات البرمجية التالية لن تعمل:

if (serialPort.IsOpen) serialPort.Close();

لأن الكائن الخاص بك لم يتم فتح المنفذ لا يمكنك إغلاقه.

أيضا يجب إغلاق والتخلص من المنفذ التسلسلي حتى بعد حدوث استثناءات

try
{
   //do serial port stuff
}
finally
{
   if(serialPort != null)
   {
      if(serialPort.IsOpen)
      {
         serialPort.Close();
      }
      serialPort.Dispose();
   }
}

إذا كنت تريد أن تكون عملية انقطاع ثم يجب عليك التحقق مما إذا كان المنفذ مفتوح ثم التراجع لفترة ثم حاول مرة أخرى، شيء من هذا القبيل.

while(serialPort.IsOpen)
{
   Thread.Sleep(200);
}

هل حاولت مغادرة الميناء فتح في التطبيق الخاص بك، ومجرد تحول دترنابل على / قبالة، ومن ثم إغلاق المنفذ عند إغلاق التطبيق الخاص بك؟ أي:

using (SerialPort serialPort = new SerialPort("COM1", 9600))
{
    serialPort.Open();
    while (true)
    {
        Thread.Sleep(1000);
        serialPort.DtrEnable = true;
        Thread.Sleep(1000);
        serialPort.DtrEnable = false;
    }
    serialPort.Close();
}

أنا لست على دراية دلالات دتر، لذلك أنا لا أعرف ما إذا كان هذا العمل.


هل هناك سبب وجيه للحفاظ على الخدمة من "امتلاك" المنفذ؟ نظرة على خدمة أوبس المضمنة - بمجرد أن أقول ذلك هناك أوبس تعلق على، على سبيل المثال، COM1، يمكنك قبلة أن وداعا الميناء. أود أن أقترح عليك أن تفعل الشيء نفسه إلا إذا كان هناك متطلبات تشغيلية قوية لتبادل المنفذ.


thomask

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


لقد حاولت تغيير موضوع العمل مثل هذا، مع نفس النتيجة بالضبط. مرة واحدة ينجح هيبرترمينال مرة واحدة في "التقاط الميناء" (في حين بلدي الموضوع هو النوم)، خدمتي لن تكون قادرة على فتح المنفذ مرة أخرى.

public void DoorOpener()
{
    while (true)
    {
        SerialPort serialPort = new SerialPort();
        Thread.Sleep(1000);
        serialPort.PortName = "COM1";
        serialPort.BaudRate = 9600;
        serialPort.DataBits = 8;
        serialPort.StopBits = StopBits.One;
        serialPort.Parity = Parity.None;
        try
        {
            serialPort.Open();
        }
        catch
        {
        }
        if (serialPort.IsOpen)
        {
            serialPort.DtrEnable = true;
            Thread.Sleep(1000);
            serialPort.Close();
        }
        serialPort.Dispose();
    }
}




serial-port