2011-09-08 21 views
7

Thỉnh thoảng một số kiểm tra tích hợp của tôi không thành công với thông báo trên. Tôi đang sử dụng mã dưới đây để sẵn sàng cổng.SerialPort UnauthorizedAccessException

  for(int i = 0; i < 5; i++) 
      { 
       try 
       { 
        port.Open(); 
        if (port.IsOpen) 
         break; 
       } 
       catch (Exception e) 
       { 
        try 
        { 
         port.Close(); 
        } 
        catch (Exception) 
        {} 
        Thread.Sleep(300); 
       } 
      } 

giả định của tôi là bởi vì nó không thể là chủ đề hiện ngăn chặn các cổng (vì nó sẽ cố gắng để đóng nó), nó phải là một chủ đề hay quá trình đó đã chết mà không dọn dẹp đúng cách (một trong các bài kiểm tra khác - không có gì khác truy cập vào cổng này). Có cách nào để đặt lại trạng thái của SerialPort sao cho luồng/quy trình mới có thể truy cập lại không?

Cảm ơn,

Richard

Trả lời

11

Đây là một lỗ hổng trong lớp SerialPort, nó sử dụng một chủ đề trợ giúp nội bộ để chờ đợi cho các sự kiện trên cổng. Nguồn của các sự kiện DataReceived, PinChanged và ErrorReceived. Lỗ hổng là trong việc thực hiện phương thức Close(), nó không chờ cho chuỗi trình trợ giúp này chấm dứt. Điều đó cần có thời gian, lượng thời gian chính xác không thể dự đoán được và có thể mất nhiều giây khi máy đặc biệt bận. Cổng vật lý không bị đóng lại cho đến khi điều này xảy ra, mở cổng trước khi luồng thoát bom với ngoại lệ 'cổng đã được sử dụng'. Cái bạn nhận được. Ngủ cho 300 msec như vậy là không đủ tốt.

Đây không phải là vấn đề bình thường, cổng nối tiếp không phải là thiết bị có thể chia sẻ. Đóng cổng nối tiếp và không thoát khỏi chương trình của bạn là nguy hiểm, một quá trình khác có thể lấy cắp cổng. Cũng cho bạn ngoại lệ này khi bạn cố mở lại. Thực hành thông thường là mở cổng khi ứng dụng của bạn khởi động và không đóng nó cho đến khi nó kết thúc.

+0

Cảm ơn Hans - điều này chỉ xảy ra trong thử nghiệm khi các quá trình thử nghiệm khác nhau được bắt đầu. –

2

Tôi không thể nhìn thấy nơi bạn đóng cổng.

Vấn đề đối với tôi không có ở đây (ngay cả khi bạn phải cấu trúc lại một chút mã) nhưng có lẽ bạn đang gọi port.Open(); khi cổng vẫn còn mở

Từ MSDN

Chỉ có một kết nối mở có thể tồn tại trên mỗi đối tượng SerialPort.

(Tôi không thể cho bạn biết lý do vì tôi không có đủ thông tin) Cũng nên nhớ rằng phương pháp đóng sẽ mất một thời gian để thực sự đóng cổng trong thực tế bạn nên chặn luồng chính cho đến khi cổng được gần (có lẽ sử dụng Thread.Join)

Từ MSDN

các thực hành tốt nhất cho bất kỳ ứng dụng là phải chờ một khoảng thời gian sau khi gọi phương thức Close trước khi cố gắng gọi phương thức Open, như cảng có thể không được đóng ngay lập tức.

để biết thêm

http://msdn.microsoft.com/en-us/library/system.io.ports.serialport.open.aspx

+0

@Massimilano - cảm ơn câu trả lời của bạn. Cổng được đóng trong khối catch sau khi ngủ cho 300ms (khi mở không một ngoại lệ được ném). –

+0

Tôi có thể thấy điều đó nhưng nó đóng cổng chỉ khi một ngoại lệ được ném. nếu cổng.Open() không ném ngoại lệ .Close() sẽ không được thực thi –

+0

Xin lỗi nếu tôi không rõ ràng. Lý do mở là thất bại là vì UnauthorizedAccessException đang được ném (đó là lý do tại sao tôi đã cố đóng). –

4

Tôi thường xuyên xác minh rằng cổng đã đóng ngay trước khi tôi khởi tạo cổng nối tiếp. Điều này giúp nếu bạn ngừng gỡ lỗi mã mà không đóng cổng nối tiếp. Ngoài ra, bạn nên đợi 250 mili giây sau khi mở hoặc đóng cổng trước khi tiếp tục với mã của mình.

try 
     { 
      if ((m_SerialPort != null)) 
      { 
       if (m_SerialPort.IsOpen) 
       { 
        m_SerialPort.Close(); 
       } 
      } 
      m_SerialPort = new SerialPort(portName, dataRate, parity, databits, stopBits.One); 
      m_SerialPort.Open(); 
      if (!m_SerialPort.IsOpen) 
      { 
       MessageBox.Show(string.Concat(portName, " failed to open")); 
      } 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message); 
     } 
0

GC.SuppressFinalizeGC.ReRegisterForFinalize nên được gọi là đi qua các SerialPort sở hữu dụ BaseStream như các tham số và không chỉ là ví dụ SerialPort.

Các vấn đề liên quan