2011-02-11 66 views
1

以下情形:寫入數據並顯示進度對話框

在一個WPF應用程序調用Log.Write入隊,這將被寫入到另一個線程不同的輸出(DB,文件)的消息。寫入的數據集的數量可以從少量到50000或更多的條目變化。用戶可以每次關閉應用程序。爲確保即使用戶試圖關閉Application.Exit上的應用程序,也會寫入所有數據,因此UI線程將調用Log.Dispose函數。 UI線程加入後臺線程以等待所有數據寫入。這發生在Application.Exit上。

現在,在此過程中顯示進度對話框會很棒。問題是,該進程不與下面的代碼移動:

// Initialize 
Log.CurrentInstance.DisposingProgress += new EventHandler<DisposingEventArgs>(Log_DisposingProgress) 

// initialize dialog 
// ... 
_dialog.Show(); 

Log.Dispose(); // in this method data is written back, threads closed and so on 

protected void SetPercentage(DisposingEventArgs e) 
{ 
    if (e.DisposingCompleted) 
     _dialog.Close(); 

    _dialog.Value = e.Percentage; 
} 

// this function is called by a timer which checks the status of the disposing process 
protected void Log_DisposingProgress(object sender, DisposingEventArgs e) 
{ 
    _dialog.Dispatcher.Invoke(new Action<DisposingEventArgs>(SetPercentage), e); 
} 

我猜這個問題occures因爲我叫Log.Dipose從UI線程。於是,我就打電話Log.Dispose與

new Action(Log.Dispose).BeginInvoke(null, null); 

這將使進度條移動的,如果我呼籲像一個按鈕單擊事件處置和應用程序仍在運行。如果我從Application.Exit調用它,我必須阻止應用程序關閉。我試用

new Thread(() => { while(_isDisposing) Thread.Sleep(100); } 

但是在這種情況下進度條仍然沒有移動。

我試圖啓動另一個UI線程,應該顯示進度對話框,但程序將會關閉。因爲當我致電Dispatcher.Run()時,關機呼叫仍將處理。

+0

您是否考慮過保留的更改的記錄,並在程序啓動時做您的更新?換言之,當程序在關閉後運行時,不要阻止應用程序完全關閉。 – 2011-02-11 16:44:08

+0

我不知道如何跟蹤這些變化?這項任務的複雜性似乎很高,只是爲了記錄回寫條目。儘管它可以很多。也許我錯誤了你的想法。 – SACO 2011-02-14 09:39:39

回答

1

後現在更長的時間,我再次嘗試。下面的代碼做什麼,我想實現:

Log.CurrentInstance.DisposingProgress += new EventHandler<DisposingEventArgs>(Log_DisposingProgress); 

var thread = new Thread(() => 
{ 
    ... 
    _dialog.Show(); 

    while (true) 
    { 
     lock (currentEventArgsLock) 
     { 
      if (currentEventArgs != null) 
      { 
       _dialog.Value = currentEventArgs.Percentage; 

       if (currentEventArgs.DisposingCompleted) 
       { 
        _dialog.Close(); 
        return; 
       } 
      } 
     } 

     Thread.Sleep(20); 
    } 
}); 


var thread2 = new Thread(() => 
{ 
    Log.Dispose(); 
}); 

thread.Start(); 
thread2.Start(); 

// make sure both threads finished 
thread.Join(); 
thread2.Join(); 

return; 


/// <summary> 
/// This function is called to notify about progress changes during disposing of Log. 
/// </summary> 
/// <param name="sender">The sender object.</param> 
/// <param name="e">The event arguments</param> 
protected void Log_DisposingProgress(object sender, DisposingEventArgs e) 
{ 
    lock (currentEventArgsLock) 
    { 
     currentEventArgs = e; 
    } 
}