2011-11-07 35 views
5

Tôi có một hình thức cửa sổ cho phép tạo nhiều giao diện điều khiển các ứng dụng của chương trình tương tự (nó gọi program.exe bất kỳ số lần) sử dụngthật sạch giết chết một ứng dụng giao diện điều khiển từ bên trong một nhóm các giao diện điều khiển ứng dụng

process.start(). 

Tôi tìm kiếm một cách để xác định một hoạt động cụ thể của ứng dụng và tiêu diệt nó một cách rõ ràng (tức là đóng sạch quá trình thứ 5 của program.exe nhưng để lại tất cả các tiến trình khác đang chạy). Tôi có thể xác định mỗi quá trình khác nhau của program.exe qua id đã được đưa ra khi các quy trình đã được bắt đầu, nhưng tôi không thể để đóng ứng dụng bất kỳ cách nào khác ngoài gọi

process.kill() 

mà không thực hiện một gần sạch của ứng dụng.

Tôi tin rằng tôi không thể sử dụng

kể từ khi ứng dụng không có một cửa sổ (nó được điều hành thông qua một giao diện điều khiển chạy ở chế độ nền). Tôi đang tìm cách để giết các quá trình bằng cách nhấn vào một nút trong GUI của tôi sau khi tôi chọn quá trình được giết từ một danh sách các quá trình đang chạy.

Lý do tôi cần điều này là vì tôi cần đóng tất cả các chủ đề và các khía cạnh nổi bật của từng quy trình trước khi đóng.

tôi xác định mỗi quy trình mới như sau,

Process process = new Process(); 
process.StartInfo = info; 

ExecutionDetails details = new ExecutionDetails(run_id, process, info, session_type, strategy_type, name, ExecutionViewModel); 

lock (_runs) 
_runs.Add(run_id, details); // will throw on Add if duplicate id, prevent duplicate 
ExecutionViewModel.NewRun(details); // add to the view model 

process.Start(); 

đâu run_id là một GUID xác định mỗi quá trình.

Trong một lớp riêng biệt, tôi có mã được thực hiện thông qua quá trình chỉ được tham chiếu thông qua dấu nhắc lệnh khởi động chương trình (ví dụ: chương trình cuộc gọi, cung cấp biến cấu hình, v.v.).

Có cách nào để tôi có thể đóng các quy trình một cách rõ ràng không? Tôi đã nghĩ rằng có một sự kiện được gọi khi tôi muốn giết quá trình này có thể hiệu quả nhưng cho đến nay tôi đã không thể có được ý tưởng đó để làm việc vì tôi không thể chỉ định quy trình nào tôi muốn đóng.

** CHỈNH SỬA - Mã của tôi để xử lý sự kiện mà tôi đã cố gắng thực hiện nhưng nó không hoạt động.

Mã Trong Main Window

public void KillOne() { 
    foreach (var details in _runs.Values) { 
     if(details.IsSelected) { 
      StrategyStateManager.SessionClosed(this, details.RunId); 
       } } } 

Mã trong StrategyStateManager (Trung lớp sử dụng để giữ các biến và các sự kiện để sử dụng trong chương trình)

public delegate void StrategyCloseEventHandler(object sender, StrategyCloseEventArgs e); 

    public static void SessionClosed(object sender, Guid id) 
    { 
     if(CloseSession != null) 
      CloseSession(sender, new StrategyCloseEventArgs(id)); 
    } 


public class StrategyCloseEventArgs : EventArgs 
{ 

    private readonly Guid id; 

    public StrategyCloseEventArgs(Guid run_id) 
    { 
     id = run_id; 
    } 

    public Guid GetRunID() 
    { 
     return id; 
    } 

} 

Mã trong quá trình đó đã được bắt đầu bởi cửa sổ chính

StrategyStateManager.CloseSession += (closeStrategy); 

void closeStrategy(object sender, StrategyCloseEventArgs e) 
    { 
     if (e.GetRunID() == run_id) 
     { 
      strategy.cleanupForShutdown(); 
      DBSaverSimple.shutdownAll(); 
      logger.Warn("Simulation run stopped by user"); 
     } 
    } 

Trả lời

4

Khả năng xảy ra ngay lập tức trong đầu là sử dụng một gói dữ liệu phát sóng có chứa thông điệp gần và id quá trình của một mà bạn muốn đóng. Mỗi quá trình giao diện điều khiển lắng nghe các gói dữ liệu phát sóng trên một cổng chung. Khi chương trình nhận được một datagram, nó phân tích cú pháp dữ liệu, kiểm tra id tiến trình đã truyền với id tiến trình riêng của nó, và nếu chúng khớp nhau, chương trình sẽ khởi động tắt máy sạch.

Giả định này, tất nhiên, bạn đã tạo một cách để chương trình tự tắt hoàn toàn.

Các gói dữ liệu phát sóng không được đảm bảo để nhận được, tất nhiên, nhưng kinh nghiệm của tôi là chúng đáng tin cậy trên một hệ thống duy nhất. Nếu bạn gặp sự cố, bạn có thể có chương trình chính của bạn gửi datagram, đợi một khoảng thời gian để xem chương trình có tắt hay không, và nếu không thì gửi lại datagram.

Một khả năng khác là tạo một tên EventWaitHandle cho mỗi quá trình mà bạn bắt đầu, chuyển tên của sự kiện đó đến ứng dụng bảng điều khiển trên dòng lệnh. Sau đó, chương trình điều khiển có thể có một chuỗi thực hiện WaitOne trên sự kiện đó. Khi sự kiện được thiết lập, chương trình khởi động tắt máy sạch sẽ. Điều này là đáng tin cậy hơn so với datagram phát sóng. Chắc chắn, nó sử dụng một xử lý cho mỗi quá trình, nhưng đó sẽ không là một vấn đề, trừ khi bạn có hàng ngàn quy trình.

Xem Send message from one running console app to another để biết ví dụ về cách sử dụng bộ điều khiển chờ đợi có tên để giao tiếp giữa các quá trình.

+0

Tôi đã mô tả ý tưởng EventWaitHandle mà bạn đã đề xuất và nó hoạt động rất tốt. Cảm ơn – jwb555

+0

Downvoter? Đó là phong tục để cung cấp một bình luận cho một lý do cho downvote. –

1

Có vẻ như bạn sẽ có trạng thái xác định trong phần tách mã lệnh được chạy bởi các tiến trình con tại điểm mà bạn muốn quá trình đó kết thúc. Tại sao bạn không gọi Process.GetCurrentProcess().Kill(); hoặc thậm chí Process.GetCurrentProcess().Close(); ở cuối đường dẫn mã đó?

Bằng cách đó khi nó được thực hiện xong nó sẽ đóng/tự hủy và các tiến trình còn lại sẽ tiếp tục chạy khi chúng thấy phù hợp (cho đến khi chúng cũng đạt đến điểm kết thúc)?

+0

Tôi không có thời gian nhất định trong mã khi tôi muốn nó chấm dứt. Việc chấm dứt được quyết định bởi một nút bấm trong GUI. Nếu tôi sử dụng Process.Kill() nó sẽ chấm dứt chương trình và không làm sạch và Process.Close() không thực sự chấm dứt quá trình nó chỉ có nghĩa là để giải phóng khung nhìn "cục bộ" trên tiến trình và các tài nguyên liên quan. – jwb555

+0

Bạn đã thử 'process.CloseMainWindow()' chưa? Nếu điều này đến từ một nút bấm, bạn chắc chắn có một cửa sổ chính. Bạn cũng có thể thử 'System.Exit()' để đóng ứng dụng. Nếu được gọi trong tiểu trình, tôi * tin * nó sẽ cung cấp cho bạn những gì bạn muốn. – Kevek

+0

Việc chấm dứt đến từ một GUI nhưng quá trình thực tế không có cửa sổ như được định nghĩa trong dấu nhắc lệnh teh để bắt đầu quá trình. Do Process.CloseMainWindow() này không làm gì cho quá trình này. System.Exit() sẽ làm việc để đóng nó nhưng tôi cần một cách để có thể gọi nó trong một quá trình cụ thể vì nhiều sẽ chạy cùng một lúc, do đó, một sự kiện hoặc một số thông báo khác sẽ cần thiết để gọi hệ thống .Exit(), mà tôi đã không thể cấy ghép cho đến nay do tình hình quá trình nhiều. – jwb555

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