2010-03-09 25 views
5

Tôi gặp sự cố khi GUI của mình xuất hiện và không bị đóng băng trong khi đang chạy (và chờ đợi) một quy trình bên ngoài. Trong trường hợp này, drivers.exe là một chương trình rất đơn giản, nơi người dùng chỉ cần nhấp vào "OK". Vì vậy, bất cứ khi nào tôi nhấp vào OK, nó thoát. Tôi đang cố gắng để chỉ đơn giản là làm cho dải trạng thái của tôi đếm số lên (thực sự nhanh) như drivers.exe đang thực hiện. Nhưng trong thực tế, GUI của tôi không bao giờ xuất hiện ở tất cả cho đến khi thoát khỏi drivers.exe.Chạy một quy trình khác mà không có GUI đóng băng

private void run_drivers() 
     { 
      Console.WriteLine("Start Driver"); 
      int driver_timeout_in_minutes = 20; 
      System.Diagnostics.Process driverproc = System.Diagnostics.Process.Start(Application.StartupPath + "\\" + "drivers.exe"); 
      driverproc.WaitForExit(driver_timeout_in_minutes * 1000 * 60); //uses milliseconds, we must convert 
     } 

     private void Form1_Load(object sender, EventArgs e) 
     { 
      ThreadStart worker = new ThreadStart(run_drivers); 
      Console.WriteLine("Main - Creating worker thread"); 
      toolStripStatusLabel1.Text = "hi"; 
      Thread t = new Thread(worker); 
      t.IsBackground = true; 
      t.Start(); 
      Console.WriteLine("Main - Have requested the start of worker thread"); 

      int i = 0; 
      while (t.IsAlive) 
      { 
       i++; 
       toolStripStatusLabel1.Text = i.ToString(); 
      } 
      Console.WriteLine("Dead"); 
     } 

Trả lời

3

Bạn nên nhìn vào một BackgroundWorker, vì nó làm tất cả công việc phân luồng cho bạn

+0

thể bạn vui lòng chỉ cho tôi như thế nào? Tôi đã làm cho nó một shot, và nó thực sự không làm việc ở tất cả. Hình thức của tôi vẫn sẽ không hiển thị ... trên thực tế. – Adam

+2

Vấn đề là vòng lặp "while (t.IsAlive)". Anh ta cần phải loại bỏ điều đó khỏi chuỗi giao diện người dùng dù anh ta có sử dụng BackgroundWorker hay không. – Phil

2

Lý do mà hình thức của bạn không hiển thị cho đến drivers.exe đã chạy là bởi vì bạn đang chạy drivers.exe từ trong số Form.Load. Form.Load xảy ra trước khi biểu mẫu được hiển thị. Hãy thử chạy drivers.exe trong Form.Shown để thay thế.

Ngoài ra, while(t.IsAlive) sẽ chặn kỹ thuật chuỗi giao diện người dùng của bạn. Nếu đó không phải là những gì bạn muốn, nó sẽ được di chuyển ra khỏi chủ đề chính. Bạn cũng có thể muốn gọi toolStripStatusLabel1.Refresh() để buộc nhãn làm mới sau khi bạn đặt văn bản.

+0

Cho dù mã đang chạy trong Form.Load hay mới hơn, chuỗi giao diện người dùng sẽ vẫn không có thời gian để vẽ màn hình khi được thực hiện như được hiển thị. –

0

không đặt bất kỳ vòng lặp nào trên chuỗi GUI. nó sẽ đóng băng ứng dụng của bạn. Vòng lặp phải nằm trên chủ đề nền nên cập nhật phương thức toolStripStatusLabel1 đến Invoke.

xem ví dụ này. chưa được kiểm tra. có lẽ nó thậm chí có thể chỉ làm việc như thế này ...

private void run_drivers() 
    { 
     Console.WriteLine("Start Driver"); 
     int driver_timeout_in_minutes = 20; 
     System.Diagnostics.Process driverproc = System.Diagnostics.Process.Start(Application.StartupPath + "\\" + "drivers.exe"); 
     int i = 0; 
     var action = new Action<int>(x => { toolStripStatusLabel1.Text = i.ToString(); }) 
     while (!driverproc.HasExited) 
     { 
      i++; 
      toolStripStatusLabel1.Invoke(action); 
     } 

     Console.WriteLine("Dead"); 
     // start another thread here... 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     ThreadStart worker = new ThreadStart(run_drivers); 
     Console.WriteLine("Main - Creating worker thread"); 
     toolStripStatusLabel1.Text = "hi"; 
     Thread t = new Thread(worker); 
     t.IsBackground = true; 
     t.Start(); 
     Console.WriteLine("Main - Have requested the start of worker thread"); 
    } 
+0

Được rồi, điều đó có ý nghĩa. Nhưng làm thế nào sau đó tôi chờ đợi để thực hiện một chức năng cho đến khi một số khác được hoàn thành? Ví dụ: giả sử tôi muốn thực thi func_2 chỉ sau khi func_2 hoàn tất, cả hai sẽ mất vài phút để hoàn tất. – Adam

+0

bắt đầu luồng mới trên dòng cuối cùng của phương thức 'run_drivers()'. chỉ cần tránh xa các vòng lặp trên giao diện GUI. –

0

Một giải pháp bạn có thể sử dụng, trong khi vẫn giữ cấu trúc mã hiện tại của bạn, là để cập nhật giao diện người dùng theo định kỳ trên một sợi timer, dừng bộ đếm thời gian khi thread hoàn tất. Làm điều này, bạn sẽ thay đổi từ một vòng lặp sang thiết kế hướng sự kiện và bạn sẽ cung cấp thời gian cho luồng giao diện người dùng để vẽ biểu mẫu của mình.

// create a System.Windows.Forms.Timer through the designer or in code. 
// give it a short interval if you want the counter to increment quickly. 

int counter; 

private void Form1_Load(object sender, EventArgs e) 
{ 
    ... 
    t.Start(); 
    counter = 0; 
    timer.Start(); 
    .... 
} 

private void timer_Tick(object sender, EventArgs e) 
{ 
    if (t.IsAlive) 
    { 
     counter++; 
     toolStripStatusLabel1.Text = counter.ToString(); 
    } 
    else 
    { 
     timer.Stop(); 
    } 
} 

(chưa được kiểm tra)

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