我有数据集ds

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");

我执行此操作时需要增加进度条。

怎么做 ?

谢谢

最佳答案

不幸的是,您不能与WriteXml()方法一起使用的DataSet或TextWriter / XmlWriter都允许您预订任何“ ValueWritten”事件,这是最干净的方法。

如果您绝对必须有一个工作进度条,该进度条将向用户显示您已编写了多少XML,则建议您派生自己的XmlWriter实现,该实现将公开并引发一个可订阅的事件,您可以使用该事件来使进度条与每个事件碰撞写。您可以在实现中包含XmlTextWriter来实际进行编写(我强烈建议您这样做),但是您不能直接从XmlTextWriter派生。这是因为将从XmlTextWriter扩展的方法不是虚拟的,因此您必须使用new关键字隐藏XmlTextWriter的实现。然后,DataSet.WriteXml(XmlWriter)重载会将您的类视为基本XmlWriter,因此您编写的隐藏XmlTextWriter的实现的方法将被忽略。

您需要权衡的其他注意事项:


在WriteXml()告知XmlWriter关闭其流之前,您将不知道写入文件的确切大小。因此,每个“碰撞”都需要某种有根据的猜测。
如果期望所有文件的大小大致相同,则可以得出平均“块与百分比”比率,这将成为您的“步骤”。
您也可以尝试直接设置进度百分比,将进度条按每次读取剩余进度的某个固定百分比移动,这会将其渐近地移向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;
}

关于c# - 我写xml时如何增加progressbar?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4606948/

10-11 13:28