2009-11-08 50 views
6

Tôi có một ứng dụng mà tôi đọc từ cổng nối tiếp, mọi thứ diễn ra tốt đẹp, cho đến khi tôi đóng ứng dụng. Khi tôi nhấp vào [X] ứng dụng chỉ đơn giản là treo, giao diện người dùng: không phản hồi.C#: Cách thích hợp để đóng SerialPort với Winforms

tôi đọc từ cổng trong xử lý sự kiện DataReceived, và tôi đóng cổng khi FormClosed xảy ra:

private void MainForm_FormClosed(object sender, FormClosedEventArgs e) 
    { 
     mySerialPort.Close(); 
    } 

Trả lời

6

Serial Port hangs while closing

Đây là một vấn đề được biết đến với lớp SerialPort và được mô tả trong Product Feedback này bài viết cũng như một số chủ đề trong các diễn đàn này. Bạn có thể nhận thấy việc loại bỏ "đóng theo thiết kế".

+1

+1, mối quan hệ này với câu hỏi trước của OP. Nhưng đối với một câu trả lời SO tốt bạn có thể đã đăng tóm tắt ngắn ** ở đây **. Giả sử trang đó di chuyển? –

+2

UNBELIEVABLE !!! đây là một lỗi đã biết trong khung làm việc mà đóng bởi MS là "hoạt động như được thiết kế !!!" +1 để tham khảo – mfeingold

+0

LOL. Xem câu trả lời của tôi dưới đây. Có một lỗi mã cổng nối tiếp nghiêm trọng trong .NET framework nhưng đây là * NOT *. –

9

Nó không phải là lỗi.

Lý do duy nhất nó sẽ treo khi bạn đóng nó là bởi vì trong xử lý sự kiện của đối tượng SerialPort của bạn, bạn đang đồng bộ hóa một cuộc gọi với chủ đề chính (thường bằng cách gọi điện thoại). Phương thức close của SerialPort chờ chuỗi EventLoopRunner của nó, nó kích hoạt các sự kiện DataReceived/Error/PinChanged để chấm dứt, nhưng vì mã của riêng bạn trong sự kiện cũng đang đợi thread chính phản hồi, bạn chạy vào tình trạng khóa chết.

Lý do báo cáo lỗi được đóng 'như được thiết kế' là do 'lỗi' nằm trong mã của riêng bạn.

+5

Yup, sử dụng BeginInvoke, không Gọi. –

+0

Cảm ơn các bạn, đó là sự thật ... BeginInvoke đã giải quyết được vấn đề của tôi. – pm89

1

Giải pháp đơn giản nhất nếu bạn chỉ muốn đóng cổng khi ứng dụng đóng, là chỉ cần không bận tâm đến Đóng() cổng. Cổng vẫn sẽ bị đóng khi ứng dụng xử lý cổng nối tiếp. Cổng sẽ có sẵn để ứng dụng của bạn mở lại khi ứng dụng khởi động lại hoặc bởi các ứng dụng khác có thể muốn sử dụng cổng.

+0

Nó sẽ treo trên vứt bỏ cũng ... khi xử lý đóng nó để bạn cho đến khi phải sử dụng BeginInvoke. Tất nhiên nó không quan trọng nếu bạn đóng ứng dụng ra .. tuy nhiên nó không quan trọng nếu bạn mở và đóng nhiều cổng nối tiếp mà không đóng ứng dụng của bạn. – cb88

5

Nếu ứng dụng của bạn đang gọi Invoke để xử lý dữ liệu được recevied, hãy thử gọi BeginInvoke thay thế.

Thay vì:

this.Invoke(d, new object[] { s, tb }); 

sử dụng:

this.BeginInvoke(d, new object[] { s, tb }); 
Các vấn đề liên quan