我有数据集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/