2010-03-18 31 views
5

Tôi có một Ứng dụng Biểu mẫu Windows (Form1) cho phép người dùng mở một Biểu mẫu khác (FormGraph). Để mở FormGraph App tôi sử dụng một sợi mở nó.
Dưới đây là đoạn code mà thread đang chạy:Tại sao chủ đề của tôi chấm dứt ngay lập tức sau khi hiển thị biểu mẫu Windows?

private void ThreadCreateCurvedGraph() 
{ 
    FormGraph myGraph = new FormGraph(); 
    myGraph.CreateCurvedGraph(...); 
    myGraph.Show(); 
} 

Vấn đề của tôi là myGraph đóng cửa ngay sau khi nó đang mở.
1) Có ai biết tại sao điều này đang xảy ra và cách làm cho myGraph vẫn mở?
2) Sau khi người dùng đóng myGraph, Làm cách nào để chấm dứt chuỗi?
Rất cám ơn!

Trả lời

0

không tạo và hiển thị biểu mẫu trong chuỗi không phải chính. làm điều đó trong chủ đề hình thức chính.

Hoặc làm điều này:

private void ThreadCreateCurvedGraph() 
{ 
    FormGraph myGraph = new FormGraph(); 
    myGraph.CreateCurvedGraph(...); 
    Application.Run(myGraph); 
} 

nhưng trước tiên phiên bản là tốt hơn

+0

Đây là những gì anh ấy làm. – TomTom

+0

đọc kỹ: "Tôi sử dụng một chuỗi mở nó." – Andrey

+0

Đọc mã của anh ấy. Vấn đề: không có máy bơm thông báo nào được thiết lập. đây là lý do chính đáng để có nhiều chuỗi giao diện người dùng. Bao giờ nhìn thấy một ứng dụng giao dịch đơn luồng - họ SUCK (gợi ý: NinjaTrader - hút cho điều này). – TomTom

0

Như một quy luật của bạn nên tránh thao tác giao diện người dùng từ chủ đề (tạo biểu mẫu là một loại thao tác với giao diện người dùng) . Bạn nên luôn thao tác với giao diện người dùng từ chuỗi chính.

+0

tạo biểu mẫu không chính xác là .... thao tác. – TomTom

+0

Nếu bạn nghĩ Biểu mẫu chỉ là một phần của giao diện người dùng chứ không phải là vùng chứa cho giao diện người dùng thì đó là. – dbemerlin

+0

nó vẫn là sai. Có những trường hợp tuyệt vời cho các chủ đề đa giao diện người dùng. – TomTom

0

Nếu mất một lúc để chuẩn bị dữ liệu cho biểu mẫu, bạn có thể làm điều đó trong một chuỗi riêng biệt để giữ cho ứng dụng luôn đáp ứng. Khi dữ liệu đã sẵn sàng, bạn có thể trả về đối tượng cho chủ đề chính để cho nó hiển thị nó.

Bạn nên khai báo biến cho đối tượng trong biểu mẫu chứ không phải cục bộ trong phương pháp, để nó tồn tại khi bạn thoát khỏi chuỗi.

Khi bạn đã sẵn sàng hiển thị biểu mẫu, bạn có thể sử dụng phương thức Gọi để thực hiện cuộc gọi phương thức sẽ được thực hiện trong chuỗi chính.

+0

Không phải những gì người dùng hỏi. anh ta khá rõ ràng trong việc MUỐN mở cửa sổ khác trong một chuỗi giao diện người dùng riêng biệt, mà - ngẫu nhiên - đôi khi có thực sự là lý do tốt (các ứng dụng giao dịch nổi tiếng với điều đó). – TomTom

+1

@TomTom: Xin đừng cố gắng đưa ra phán quyết về những gì OP thực sự muốn. Rõ ràng là một chủ đề hiện đang được sử dụng, nhưng nó không rõ ràng rằng nó thực sự là giải pháp mong muốn. Chỉ vì OP yêu cầu một cái gì đó không có nghĩa là nó là giải pháp đúng. Nếu người ta chỉ bao giờ thèm hỏi những gì đã được hỏi, rất nhiều câu hỏi không thể được trả lời với bất cứ điều gì khác sau đó "có" hoặc "không", như câu hỏi thực sự hỏi không phải là những gì có nghĩa là bằng cách đặt câu hỏi. – Guffa

+0

xin vui lòng không cố gắng làm cho một phán quyết về OP thực sự muốn. Đọc bài của anh ấy. Làm theo ví dụ của mình và khấu trừ những gì anh ta cố gắng làm. Đừng cho rằng lập trình viên là một thằng ngốc. – TomTom

0

Biểu mẫu sẽ đóng vì chuỗi đã hoàn tất và do đó được miễn phí cùng với các hồ sơ của nó (biểu mẫu). Để làm cho chuỗi tiếp tục chạy, bạn cần một vòng lặp

ví dụ:

private void ThreadCreateCurvedGraph() 
{ 
    FormGraph myGraph = new FormGraph(); 
    myGraph.CreateCurvedGraph(...); 
    myGraph.Show(); 
    while (myGraph.IsOpen) 
    { 
     //process incoming messages <- this could be fun on a thread.... 
    } 
} 

Bạn sẽ cần một phương pháp thiết ISOpen (như một thời gian chờ hoặc nút) và rõ ràng bạn sẽ cần phải thực sự tạo ISOpen như một thuộc tính của hình thức và thiết lập nó là true khi biểu mẫu được tạo ra .

Tôi sẽ thêm ở đây giống với những người dùng khác ... Bạn nên có lý do chính đáng để không sử dụng chuỗi chính.

+0

Vì vậy, nhiều người ở đây không thực sự biết những điểm nhấn của nhiều máy bơm tin nhắn - nó đau. RTFM, các bạn. Có những lý do thực sự tốt để thực hiện giao diện người dùng đa luồng - tôi có một giao diện người dùng sử dụng tối đa 6 chuỗi giao diện người dùng cho 6 cửa sổ. Mà tất cả đều bận rộn sơn lại. Điều này được hỗ trợ đầy đủ. – TomTom

1

Vấn đề chính bạn cho là bạn không thiết lập bơm thông báo trong chuỗi mới.

Kiểm tra

Run multiple UI Threads

cho một cái nhìn tổng quan tốt như thế nào để chạy một giao diện người dùng perforamnce cao sử dụng nhiều thread (mỗi hình thức/nhóm các mẫu đính kèm).

Điều cơ bản bạn bỏ lỡ là cuộc gọi đến Application.Run để thiết lập máy bơm tin nhắn trên chuỗi giao diện người dùng riêng biệt.

Tôi nghĩ rằng khi hình thức cuối cùng của máy bơm tin nhắn đóng - nó sẽ vứt bỏ chính nó và kết thúc. Lưu ý rằng tất cả các ASSUMES bạn muốn mở cửa sổ trong một chuỗi giao diện người dùng riêng biệt ... nếu không bạn cần gọi lại luồng giao diện người dùng chính để tạo và thao tác tất cả cửa sổ, vì vậy nó được gắn vào máy bơm thông báo hiện tại. Có trường hợp tốt cho cả hai - một giữ cho các hiệu ứng đơn giản, cái kia cho phép hiệu năng LOT nhiều hơn vì mỗi cửa sổ có một bơm thông điệp riêng biệt và do đó có thể hoạt động riêng - ví dụ này được sử dụng rất nhiều trong các ứng dụng giao dịch có thể cần cập nhật đồ thị một số màn hình và nút cổ chai havea nếu chạy đơn luồng trong giao diện người dùng.

-1

Có lẽ đây là thu gom rác thải:

Sau ThreadCreateCurvedGraph() lối thoát hiểm, myGraph đi ra khỏi phạm vi và số lần đóng.

Bạn cần tổ chức một cách của chuỗi để giữ cho phiên bản và chờ (sử dụng tính năng chờ chặn) để đóng.

Edit: Ví dụ thêm:

Application.Run(myGraph) 

đến cuối của phương pháp.
(Xem nhận xét từ TomTom)

+0

Không, người dùng cần thiết lập một BƠM THÔNG ĐIỆP để xử lý các thông điệp cửa sổ của chuỗi giao diện người dùng mới. – TomTom

+0

@TomTom: Có phải đó là: 'Application.Run (myGraph)' mà cả hai có thể giữ lại thể hiện và đợi nó đóng lại? – quamrana

+0

Chính xác. Nó sẽ thiết lập một máy bơm tin nhắn và chờ cho đến khi cửa sổ cuối cùng đóng nó. Điều này tương tự như những gì xảy ra trong chủ đề chính, mà lúc bắt đầu không phải là một giao diện người dùng nối chuỗi hoặc (đó là lý do tại sao bạn đọc Application.Run ở đó). – TomTom

-1

Còn nếu bạn hiển thị biểu mẫu như thể đó là Hộp thoại? Bạn có thể sử dụng

private void ThreadCreateCurvedGraph() 
{ 
    FormGraph myGraph = new FormGraph(); 
    myGraph.CreateCurvedGraph(...); 
    myGraph.ShowDialog(); 
} 

Bằng cách này cuộc gọi sẽ chặn cho đến khi biểu mẫu myGraph bị đóng. Khi bạn có myGraph được tạo trên một thread tách biệt, việc gọi ShowDialog chặn sẽ chỉ chặn luồng đó.

+0

Không phải là một giải pháp và bỏ qua toàn bộ những gì là sai. – TomTom

+0

Ý tưởng tuyệt vời! Tôi nghĩ tôi sẽ làm như bạn nói. – menachem

+0

Theo như tôi biết Nó hoạt động vì vậy tôi không biết tại sao bạn đang bỏ phiếu cho tôi. –

5

Sự cố không nằm trong đoạn mã được đăng. Bạn sẽ cần phải bắt đầu một vòng lặp tin nhắn mới với Application.Run() hoặc Form.ShowDialog(). Bạn cũng sẽ cần phải chăm sóc các thuộc tính luồng nên nó phù hợp để hoạt động như một chuỗi giao diện người dùng. Ví dụ:

Thread t = new Thread(() => { 
    Application.Run(new Form2()); 
    // OR: 
    //new Form2().ShowDialog(); 
    }); 
    t.SetApartmentState(ApartmentState.STA); 
    t.IsBackground = true; 
    t.Start(); 

Có một số lựa chọn khó xử tại đây. Biểu mẫu không thể được sở hữu bởi bất kỳ biểu mẫu nào trên luồng chính của bạn, thường gây ra các vấn đề về trật tự Z. Bạn cũng sẽ cần phải thực hiện điều gì đó có ý nghĩa khi biểu mẫu chính của chuỗi giao diện người dùng bị đóng. Sloppily giải quyết ở đây bằng cách sử dụng IsBackground.

Windows được thiết kế để hỗ trợ nhiều cửa sổ chạy trên một chuỗi. Chỉ sử dụng mã như thế này nếu bạn thực sự là phải. Bạn không bao giờ phải ...

+0

Tuyệt vời ngoại trừ phần cuối cùng - bạn không bao giờ phải làm vậy. Đã từng thấy một ứng dụng giao dịch ... có quá nhiều cập nhật giao diện người dùng bị tụt hậu trên 6 màn hình;) Có nhu cầu. – TomTom

+0

@TomTom: Tôi không biết tại sao ở đây không sai khi đặt một ShowDialog ở đây như tôi đã nói. –

0

Tại sao bạn tạo biểu mẫu trên một chuỗi mới? Có những lúc bạn cần sử dụng một chuỗi mới nhưng lần khác bạn có thể sử dụng form.ShowDialog() trên luồng chính.

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