2009-08-30 28 views
6

Tôi có một lớp (NamedPipeManager) có một luồng (PipeThread) chờ kết nối NamedPipe sử dụng (ConnectNamedPipe) và sau đó đọc (ReadFile) - đây là các cuộc gọi chặn (không chồng chéo) - tuy nhiên có khi tôi muốn bỏ chặn chúng - ví dụ khi lớp gọi điện thoại cố gắng để ngăn chặn các NamedPipeManager ...Làm thế nào để bỏ chặn ConnectNamedPipe và ReadFile? [C#]

Làm thế nào tôi có thể ngắt nó? Sử dụng Thread.abort? Thread.interrupt? Có cách nào thích hợp để xử lý việc này không? Tham khảo mã dưới đây minh họa tình hình hiện tại của tôi

main() 
{ 
    NamedPipeManager np = new NamedPipeManager(); 
     ... do stuff ... 
    ... do stuff ... 
    np.Stop();  // at this point I want to stop waiting on a connection 
} 


class NamedPipeManager 
{ 
private Thread PipeThread; 

public NamedPipeManager 
{ 
    PipeThread = new Thread(new ThreadStart(ManagePipes)); 
    PipeThread.IsBackground = true; 
    PipeThread.Name = "NamedPipe Manager"; 
    PipeThread.Start(); 
} 

private void ManagePipes() 
{ 
    handle = CreateNamedPipe(..., PIPE_WAIT, ...); 
    ConnectNamedPipe(handle, null);  // this is the BLOCKING call waiting for client connection 

    ReadFile(....);    // this is the BLOCKING call to readfile after a connection has been established 
    } 


public void Stop() 
{ 
    /// This is where I need to do my magic 
    /// But somehow I need to stop PipeThread 
    PipeThread.abort();  //?? my gut tells me this is bad 
} 
}; 

Vì vậy, trong chức năng Stop() - làm thế nào có thể tôi một cách duyên dáng mở khóa các cuộc gọi đến ConnectNamedPipe (...) hoặc ReadFile (...)?

Mọi trợ giúp sẽ được đánh giá cao. Cảm ơn,

Trả lời

4

Bắt đầu với Windows Vista, có một hoạt động CancelSynchronousIO khả dụng cho chủ đề. Tôi không nghĩ rằng có một wrapper C# cho nó, vì vậy bạn sẽ cần phải sử dụng PInvoke để gọi nó.

Trước Vista, thực sự không có cách nào để thực hiện thao tác này một cách duyên dáng. Tôi sẽ khuyên bạn không nên sử dụng hủy bỏ chuỗi (có thể hoạt động, nhưng không đủ điều kiện như là duyên dáng). Cách tiếp cận tốt nhất của bạn là sử dụng IO chồng lên nhau.

+0

Điều này có áp dụng cho cả hai trường hợp (ConnectNamedPipe & ReadFile) không? Tôi có thể tìm cách vượt qua ConnectNamedPipe bằng cách giả mạo một kết nối sẽ bỏ chặn nó và sau đó thoát (dựa trên bool) - nhưng tôi không thể xem cách tôi có thể bỏ chặn một ReadFile bao giờ ... Làm thế nào để thực hiện điều này làm xong? Phải có một số cách không asynch để xử lý tình huống này. – Shaitan00

+0

BTW - đây là để chạy trên Windows 2000 và XP ... không có Vista bất cứ lúc nào sớm .. Ngoài ra sử dụng .Net 2.0 ... Cảm ơn, – Shaitan00

+0

Một cách sẽ là để xác định một thời gian trên tất cả các hoạt động, và sau đó về cơ bản thực hiện bỏ phiếu (ví dụ: thực hiện thao tác đọc cho, ví dụ, 1s, sau đó kiểm tra xem chuỗi có nên hủy bỏ hay không, nếu không, tiếp tục đọc). Tuy nhiên, có vẻ như Microsoft thực sự không tin vào thời gian chờ, vì vậy không có API để chỉ định chúng. Xem thêm http://stackoverflow.com/questions/593175/breaking-readfile-blocking-named-pipe-windows-api –

3

Nó dường như được làm việc trên VC6.0, WinXP nếu tôi cố gắng để làm gián đoạn ConnectNamedPipe bởi DeleteFile("\\\\.\\pipe\\yourpipehere");

Vì vậy, chỉ cần chỉ định tên, không xử lý.

+0

Thực tế, DeleteFile trong nội bộ mở tập tin xử lý theo tên, do đó, điều này tương đương với việc gọi CreateFile(). –

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