2014-01-23 69 views
0

所以我的主窗體有一個按鈕,當這個非常長的複製過程完成時,我可以啓用它。這個複製過程每10分鐘發生一次,並檢查更新等。我堅持如何讓進程通知主機完成複製。這是我到目前爲止有:如何在進程完成時更新UI表單?

public partial class mainForm : Form 
{ 
....//initialize some stuff 

    private void TimerEventProcessor(object sender, EventArgs e) 
    { 
    .... 
    copy.GetNewCopy(); 
    } 
} 

class Copy 
{ 
    private bool IsCopyComplete; 
    .... 
    public void GetNewCopy() 
    { 
     Process proc = new Process(); 
     IsCopyComplete = false; 
     proc.EnableRaisingEvents = true; 
     proc.Exited += new EventHandler(myProcess_Exited); 
     proc.Start(); 
    } 

    private void myProcess_Exited(object sender, System.EventArgs e) 
    { 
     IsCopyComplete = true; 

     // how to trigger mainform that process is complete? 
    } 

} 
+0

考慮使用基於'Task'圖案:在異步4.5:在異步的API啓用進展和取消](HTTP: //blogs.msdn.com/b/dotnet/archive/2012/06/06/async-in-4-5-enabling-progress-and-cancellation-in-async-apis.aspx)。 – Noseratio

回答

1

你可以叫Invoke

private void myProcess_Exited(object sender, System.EventArgs e) 
{ 
    IsCopyComplete = true; 

    button1.Invoke(new Action(() => button1.Enabled = true)); 
} 

這裏有製作thread-safe calls to the UI的文章。

有幾種創建線程的方法。由於其內置的用於更新UI的功能,我最喜歡的是BackgroundWorker Thread(雖然它不適合每種情況)。


您可以通過以下形式的參考類,雖然這通常似乎是錯誤的莫名其妙。該類不應該意識到您的表單的UI組件。

我會做的是創建一個EventHandlerExited事件可以發佈到。 (您可以附加到多個事件,因此如果您仍然需要設置IsCopyComplete = true,那麼也請離開該事件。)當Exited事件觸發時,它會在不知道是否訂閱了其他事件的情況下調用「ProcessExited」EventHandler

class Copy 
{ 
    public event EventHandler ProcessExited; 

    private bool IsCopyComplete; 
    .... 
    public void GetNewCopy() 
    { 
     Process proc = new Process(); 
     IsCopyComplete = false; 
     proc.EnableRaisingEvents = true; 
     proc.Exited += ProcessExited; 
     proc.Exited += new EventHandler(myProcess_Exited); 
     proc.StartInfo = new ProcessStartInfo("cmd.exe"); // specify your process - replace cmd.exe with whatever's appropriate 
     proc.Start(); 
    } 

    private void myProcess_Exited(object sender, System.EventArgs e) 
    { 
     IsCopyComplete = true; 
    } 
} 

然後在您的主窗體中,您可以訂閱該事件。

public partial class mainForm : Form 
{ 
    ....//initialize some stuff 

    public class mainForm() 
    { 
     ... 
     // not sure where you're instantiating `copy` - you may have to move this 

     copy.ProcessExited += (s, a) => 
      button1.Invoke(new Action(() => button1.Enabled = true)); 
     ... 
    } 

    private void TimerEventProcessor(object sender, EventArgs e) 
    { 
     copy.GetNewCopy(); 
    } 
} 
+0

如果進程處於不同的類中,如何訪問button1? – JLYK

+0

@JLYK編輯答案。 –

1

有很多方法可以做到這一點。這裏是一個

聲明處理程序方法在你的MainForm然後sunscribe如下

proc.Exited += new EventHandler(MainForm1.myProcess_Exited); 
+0

儘管如此,這使得該類更少重用。如果不同的表單需要在該類中調用相同的方法呢? –

+0

按問題回答問題。 「我的主窗體有一個按鈕」 – electricalbah