2009-07-19 25 views
13

Vì lợi ích của đối số, hãy xem xét một chuỗi giao diện người dùng là một chuỗi đã có cuộc gọi đến Application.Run() hoặc một trong những quá tải của nó được gọi trên đó và có một vòng lặp tin nhắn đang hoạt động đang chạy.Cách phát hiện xem chúng tôi có đang ở trên một chuỗi giao diện người dùng không?

Có cách nào để phát hiện nếu chúng tôi hiện đang thực hiện trên một chuỗi không?

Lý do tôi muốn điều này là do tôi có một lớp học có chức năng riêng tư dài hạn. Bản thân lớp đã được đa luồng và việc sử dụng lớp này là như vậy mà nó có thể được sử dụng từ giao diện người dùng hoặc từ các chủ đề nền đang xử lý. Chức năng này cũng rơi vào lưới này. Nhưng tôi không muốn nó chặn luồng UI. Vì vậy, tôi muốn phát hiện nếu tôi đang chạy trên một thread UI và nếu như vậy, ngã ba cuộc gọi chức năng thành một chủ đề nền (có thể là ThreadPool, nhưng đó là một vấn đề không cho cuộc thảo luận này). Điều này hoàn toàn được xử lý tốt, nhưng các chủ đề nền có thể dựa vào đầu ra của hàm, vì vậy việc chặn chúng là tốt hơn, trong khi luồng giao diện người dùng đang truy cập nó theo cách "đặt và quên" hơn.

Trả lời

7

Tôi cho rằng đó là loại quyết định mà người gọi nên thực hiện. Bạn luôn có thể viết các phương thức wrapper để làm cho nó dễ dàng hơn - nhưng điều đó có nghĩa là bạn sẽ không gặp vấn đề gì với người gọi đang ở trong tình huống "lẻ" (ví dụ như một khung UI mà bạn không biết hoặc một cái gì đó khác với vòng lặp sự kiện)) và bạn đưa ra quyết định sai cho họ.

Nếu phương pháp bao giờ cần cung cấp phản hồi đúng chủ đề, tôi sẽ chuyển vào một số ISynchronizeInvoke (được triển khai bởi Control) để thực hiện điều đó theo cách không phụ thuộc vào giao diện người dùng.

12

Nếu bạn có quyền truy cập vào số Form hoặc Control, bạn có thể kiểm tra thuộc tính InvokeRequired; điều này sẽ trả lại false nếu bạn đang ở trên chuỗi giao diện người dùng và true nếu bạn không .. Nếu điều đó xảy ra trong ngữ cảnh mà bạn không thể kiểm tra trên Control, bạn có thể dễ dàng thiết lập thuộc tính tĩnh trong chương trình mà bạn có thể kiểm tra. Lưu trữ một tham chiếu đến Thread.CurrentThread lúc khởi động, và so sánh Thread.CurrentThread để tham khảo khi bạn cần phải biết:

static class Program 
{ 
    private static Thread _startupThread = null; 

    [STAThread] 
    static void Main() 
    { 
     _startupThread = Thread.CurrentThread; 

     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     Application.Run(new Form1()); 
    } 

    public static bool IsRunningOnStartupThread() 
    { 
     return Thread.CurrentThread == _startupThread; 
    } 
} 

Bằng cách gọi Program.IsRunningOnStartupThread bạn sẽ nhận được một bool nói nếu bạn hay không.

+0

Khởi động không nhất thiết phải là luồng GUI, hoặc chỉ là luồng GUI. –

+1

WRONG: InvokeRequired trả về true nếu trên một "thread khác với thread được tạo trên" –

+1

@Rico: Vâng, tất nhiên. Tôi không thể tin rằng typo đã ngồi đó trong ba năm qua và không ai nhận thấy. Cảm ơn bạn đã bắt nó, tôi đã cập nhật câu trả lời cho phù hợp. –

8

bool isMessageLoopThread = System.Windows.Forms.Application.MessageLoop;

+0

Đây là câu trả lời đơn giản nhất cho mục đích của tôi. – ToolmakerSteve

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