2011-01-05 68 views
2

我有數據集DS當我編寫xml時如何增加進度條?

DataSet ds = new DataSet(); 
SQL = "SELECT * FROM MyCount"; 
adp = new SqlCeDataAdapter(SQL, Conn); 
adp.Fill(ds, "MyCount"); 
adp.Dispose(); 

我寫這樣的XML:ds.WriteXml(@"\MyPath\Count.xml");

我需要提高進度,當我做這個動作。

該怎麼辦?

感謝

+0

你是否(例如)在按鈕點擊操作? – 2011-01-05 17:16:04

+3

你將如何確定進度? WriteXml調用是否需要一定的時間? – SwDevMan81 2011-01-05 17:17:25

回答

5

不幸的是,該數據集,也可以用中WriteXML()方法中使用的TextWriter/XmlWriter的讓你訂閱任何「ValueWritten」事件,這將是做最徹底的方法。

如果您絕對必須有一個工作進度條,它會向用戶顯示您已經寫入了多少XML,我建議您派生自己的XmlWriter實現,該實現將公開並觸發一個可以用來打擊您的可訂閱事件進度條與每個寫入。你可以在你的實現中包含一個XmlTextWriter來實際完成寫作(我強烈建議這麼做), ,但是你不能直接從XmlTextWriter派生。這是因爲您將從XmlTextWriter擴展的方法不是虛擬的,因此您必須使用 new關鍵字來隱藏XmlTextWriter的實現。 DataSet.WriteXml(XmlWriter)重載然後將您的類視爲基礎XmlWriter,因此您編寫的用於隱藏XmlTextWriter實現的方法將被忽略。

你需要權衡其他因素:

  • 你不會知道的書面文件,直到您的XmlWriter的確切大小被告知關閉()通過其流中WriteXML()。因此,每個「凹凸」都需要進行某種有教育的猜測。
  • 如果您的所有文件預計大致相同,您可以想出一個平均的「塊到百分比」比例,這將成爲您的「步驟」。
  • 您也可以嘗試直接設置進度百分比,將進度條移動到每次讀取的剩餘進度的某個固定百分比,這會使其逐漸趨於100%,但在作家關閉之前無法達到它(並觸發事件說你已經完成)。
  • 與所有事件一樣,確保在處置發佈者或訂閱者時正確釋放所有事件訂閱。
  • 與所有的UI元素一樣,確保你沒有試圖調用與UI線程之外的進度條一起工作的處理程序。這限制了您的多線程選項,因爲從另一個線程調用WriteXml將導致處理程序在該線程中運行。但是,您必須允許UI線程處理一些時間來重新繪製條形圖,因此平面單線程選項也不起作用。考慮在幕後使用異步寫入,和/或在更新進度條後執行Thread.Yield()。

編輯:其實,因爲XmlWriter的聲明瞭XmlTextWriter對象必須實現的抽象方法,你可以進一步覆蓋它們在你的自定義類,這樣你就可以直接從XmlTextWriter的繼承。

一些示例代碼:

public class ObservableXmlTextWriter: XmlTextWriter 
{ 
    public delegate void XmlWriteHandler(object sender, XmlWriteEventArgs e); 

    public event XmlWriteHandler XmlWritten; 

    public event EventHandler XmlWriteComplete; 

    public class XmlWriteEventArgs:EventArgs 
    { 
     public object Value{get; private set;} 
     public XmlWriteEventArgs(object value) {Value = value;} 
    } 

    public override WriteValue(string value) 
    { 
     base.WriteValue(value); 
     if(XmlWritten != null) XmlWritten(this, new XmlWriteEventArgs(value)); 
    } 

    public override WriteValue(int value) 
    { 
     base.WriteValue(value); 
     if(XmlWritten != null) XmlWritten(this, new XmlWriteEventArgs(value)); 
    } 

    ... //override ALL Write methods to fire XmlWritten as above 

    //Dispose will call Close(), so just make sure to do one or the other 
    public override Close() 
    { 
     base.Close(value); 
     if(XmlWriteComplete!= null) XmlWriteComplete(this, new EventArgs())); 
    } 
} 

... 

public void XmlWriteHandler(object sender, XmlWriteEventArgs e) 
{ 
    //Feel free to come up with your own algorithm for approaching 100%; 
    //the number of times this event fires will be proportional to the 
    //number of data elements (rows * columns) in the DataSet. 
    MyProgressBar.Increment((MyProgressBar.Maximum - MyProgressBar.Value) * .05) 
} 

public void XmlWriteCompleteHandler(object sender, EventArgs e) 
{ 
    MyProgressBar.Value = MyProgressBar.Maximum; 
} 
+0

感謝您的幫助,我可以得到任何示例代碼? – Gold 2011-01-05 17:44:51

1

這是一個安全的賭注,你將不會被字節通知,讓字節不管你去什麼樣的方式與標準控制。想想這意味着多少開銷,特別是當每個人都在努力批量寫入時。

你有2種方式真正更新進度條:

  • 您設置的進度條「進步」爲寫指定金額,並跳過一次寫操作完成;這意味着猜測並提供一個非常「滑雪」的進度條,特別是如果這個寫入是進度條計數的主要部分。
  • 你完全放棄了確定性的進度條,而是使用其中一個旋轉的進度條,即從左到右反覆進行的進度條。你可以在Windows中看到很多這樣的例子。
0

你需要更清楚我的想法。 progressBar希望您輸入Min值(起點)和Max值(終點),並且要在performtep()函數中傳遞多少步。如果您說1,它會將1增加1. PerformStep()會增加您的酒吧。但如果你想立即看到它,你必須使用

progressBar1.PerformStep(); 
Application.DoEvents(); 

通常我在for或foreach循環中使用progressBar。 There is an example of usage:

在你的問題,因爲我看到你沒有任何循環。那麼您如何看待使用progressBar?