2012-01-24 23 views
10

Ứng dụng giao diện điều khiển của tôi đang thực hiện một chuỗi hoàn toàn dành cho giao diện người dùng, nó dành rất nhiều thời gian chặn trên Console.ReadLine() (cuộc gọi này dành thời gian sâu bên trong ruột của Windows, ngoài tầm kiểm soát của khung công tác .NET). .Làm cách nào để hủy bỏ một luồng khác trong .NET, khi chuỗi đã nói đang chạy Console.ReadLine?

Tôi cần phải hủy chủ đề này. Tuy nhiên, mã sau dường như không hoạt động:

this.UserInterfaceThread.Abort(); 

Bất kỳ ý tưởng nào? Thread.Interrupt() có được sử dụng không?

Cập nhật

Như Hans passant chỉ ra:

Các CLR áp đặt quy tắc khá lành mạnh về tình trạng của một thread khi nó hủy bỏ nó. Các hiểm họa của Thread.Abort() được biết đến, những gì chắc chắn không bao giờ có thể làm việc một cách đáng tin cậy là hủy bỏ một luồng đang thực thi mã không được quản lý. Đó là trường hợp khi bạn gọi Console.ReadLine(), luồng được chôn sâu bên trong mã hệ điều hành Windows.

Giải pháp là chỉ cần nhấn phím tắt [enter] vào ứng dụng bảng điều khiển hiện đang chạy, để mở khóa Console.ReadLine(), vì vậy, chuỗi sẽ hủy ngay lập tức.

Chúng tôi không thể sử dụng SendKeys vì điều này là dành riêng cho biểu mẫu cửa sổ và cũng yêu cầu cửa sổ hiện tại cần lấy nét.

Giải pháp là sử dụng thư viện tại số inputsimulator.codeplex.com để kết thúc cuộc gọi Windows SendInput().

Xem mẫu mã:

.NET call to send [enter] keystroke into the current process, which is a console app?

+0

bản sao có thể có của [Cách thêm Thời gian chờ vào Bảng điều khiển.ReadLine()?] (Http://stackoverflow.com/questions/57615/how-to-add-a-timeout-to-console-readline) –

+3

'Thread.Abort' [là ác] (http://www.interact-sw.co.uk/iangblog/2004/11/12/cancellation). – spender

+0

@ Dimitrov: Nó không phải là một bản sao. Câu hỏi này đề cập đến cách hủy bỏ một luồng đang chạy một cá thể duy nhất của Console.ReadLine(). – Contango

Trả lời

4

Sử dụng SendKeys và mô phỏng phím ENTER. Nhận trợ giúp here.

Chúc may mắn.

+1

Cảm ơn lời khuyên. Tôi đang sử dụng ứng dụng Console, vì vậy SendKeys có thể không hoạt động - tôi đang xem xét nó ngay bây giờ. – Contango

+0

Chỉ cần tìm thấy http://inputsimulator.codeplex.com/ dường như nó có thể mô phỏng tổ hợp phím trong các ứng dụng Console. – Contango

+0

Đã kết thúc bằng http://inputsimulator.codeplex.com/. Xem câu trả lời đầy đủ ở đây: http://stackoverflow.com/questions/9016087/net-call-to-send-enter-keystroke-into-the-current-process-which-is-a-console – Contango

6

CLR áp đặt các quy tắc khá lành mạnh về trạng thái của một chuỗi khi nó hủy bỏ nó. Các hiểm họa của Thread.Abort() được biết đến, những gì chắc chắn không bao giờ có thể làm việc một cách đáng tin cậy là hủy bỏ một luồng đang thực thi mã không được quản lý. Đó là trường hợp khi bạn gọi Console.ReadLine(), luồng được chôn sâu bên trong mã hệ điều hành Windows.

Bạn sẽ phải thực hiện việc này theo cách khác. Một cách tiếp cận rõ ràng ngay lập tức là bạn cho phép luồng 'giao diện người dùng' này dừng chương trình thay vì theo cách khác. Có thể đơn giản như lệnh "thoát" hoặc câu tục ngữ "Nhấn phím bất kỳ để tiếp tục".

Hoặc đặt thuộc tính IsBackground của luồng thành true. Bây giờ bạn không phải hủy bỏ nó, Windows sẽ chấm dứt nó khi nó tắt quá trình sau khi phương thức Main() của bạn thoát ra.

+0

Cảm ơn bạn đã giải thích những gì đang xảy ra ở đây. Tôi có một ý tưởng khác: làm thế nào về poking phím [nhập] vào ứng dụng giao diện điều khiển, buộc các chủ đề để thức dậy và hủy bỏ? Có một phương pháp để làm điều này: System.Windows.Forms.SendKeys.SendWait() – Contango

+0

Đó là quá xấu xí, SendKeys() là rất không đáng tin cậy. Bạn có thể nhận được Console.ReadLine() để quay trở lại bằng cách [đóng giao diện điều khiển đầu vào] (http://stackoverflow.com/a/9479797/17034) –

2

Tôi vừa thử nghiệm nó, không Thread.Abort() cũng không Thread.Interrupt() hoạt động trên chuỗi đang gọi tới Console.ReadLine(), ngay cả khi gọi điện qua số StreamReader(new BufferedStream(...)).

Tôi thậm chí đã thử gọi Console.In.Close()Dispose().Có vẻ như một khi bạn đang đọc, bạn thực sự ở đó; kỳ lạ vì điều đó dường như phá vỡ thiết kế của các luồng.

Nó thực sự trông giống như lựa chọn duy nhất của bạn là sử dụng các câu trả lời được đề cập bởi @ Darin-Dimitrov

Edit: Knocked nhau ra khỏi danh sách: Cố gắng gọi win32 api FreeConsole. Gây ra một ngoại lệ tham nhũng bộ nhớ từ cuộc gọi Console.ReadLine().

+0

Tôi có một ý tưởng khác: cách poking phím [enter] vào giao diện điều khiển ứng dụng, buộc các chủ đề để thức dậy và hủy bỏ? Có một phương pháp để làm điều này: System.Windows.Forms.SendKeys.SendWait() – Contango

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