C# 是否仍然可以计算或获取在ProgressBar中显示的序列化时间?
我使用的是C.net 4.0,没有找到任何可行的方法,但也许你知道 我以这种方式进行序列化:C# 是否仍然可以计算或获取在ProgressBar中显示的序列化时间?,c#,.net,serialization,progress-bar,binaryformatter,C#,.net,Serialization,Progress Bar,Binaryformatter,我使用的是C.net 4.0,没有找到任何可行的方法,但也许你知道 我以这种方式进行序列化: public static void SaveCollection<T>(string file_name, T list) { BinaryFormatter bf = new BinaryFormatter(); FileStream fs = null; try { fs = new FileStream(Application.Sta
public static void SaveCollection<T>(string file_name, T list)
{
BinaryFormatter bf = new BinaryFormatter();
FileStream fs = null;
try
{
fs = new FileStream(Application.StartupPath + "/" + file_name, FileMode.Create);
bf.Serialize(fs, list);
fs.Flush();
fs.Close();
}
catch (Exception exc)
{
if (fs != null)
fs.Close();
string msg = "Unable to save collection {0}\nThe error is {1}";
MessageBox.Show(Form1.ActiveForm, string.Format(msg, file_name, exc.Message));
}
}
我不相信有。我的建议是,对重复测量数百或数千次的序列进行计时,取平均值,然后将其用作计算序列进度的常数。我认为没有。我的建议是,对重复测量数百或数千次的序列进行计时,取平均值,然后将其用作计算序列进度的常数。您可以启动一个以特定频率运行的计时器,例如每秒4次,但这实际上与任何事情都没有关系,只与您希望更新进度的频率有关,该进度计算数据当前传输所需的时间,然后估计剩余的时间。例如:
private void timer1_Tick(object sender, EventArgs e)
{
int currentBytesTransferred = Thread.VolatileRead(ref this.bytesTransferred);
TimeSpan timeTaken = DateTime.Now - this.startDateTime;
var bps = timeTaken.TotalSeconds / currentBytesTransferred;
TimeSpan remaining = new TimeSpan(0, 0, 0, (int)((this.totalBytesToTransfer - currentBytesTransferred) / bps));
// TODO: update UI with remaining
}
这假设您正在更新另一个线程上传输的This.bytest,并且您的目标是任何CPU。您可以启动一个以特定频率运行的计时器,例如每秒4次,但这实际上与任何事情都没有关系,只与您希望更新进度的频率有关,该进度计算当前传输数据所用的时间,然后估计剩余的时间。例如:
private void timer1_Tick(object sender, EventArgs e)
{
int currentBytesTransferred = Thread.VolatileRead(ref this.bytesTransferred);
TimeSpan timeTaken = DateTime.Now - this.startDateTime;
var bps = timeTaken.TotalSeconds / currentBytesTransferred;
TimeSpan remaining = new TimeSpan(0, 0, 0, (int)((this.totalBytesToTransfer - currentBytesTransferred) / bps));
// TODO: update UI with remaining
}
这假设您正在另一个线程上更新此.ByTestTransferr,并且您的目标是任何CPU。因此,假设您使用“实际上事先知道”对象图的大小,这本身可能很困难,但假设您这样做:。您可以这样做:
public class MyStream : MemoryStream {
public long bytesWritten = 0;
public override void Write(byte[] buffer, int offset, int count) {
base.Write(buffer, offset, count);
bytesWritten += count;
}
public override void WriteByte(byte value) {
bytesWritten += 1;
base.WriteByte(value);
}
}
然后你可以像这样使用它:
BinaryFormatter bf = new BinaryFormatter();
var s = new MyStream();
bf.Serialize(s, new DateTime[200]);
这将在写入字节时为您提供字节,因此您可以使用它计算时间。注意:您可能需要重写stream类的其他几个方法 那么,假设您使用“实际上事先知道对象图的大小”,这本身可能很困难,但假设您确实知道:。您可以这样做:
public class MyStream : MemoryStream {
public long bytesWritten = 0;
public override void Write(byte[] buffer, int offset, int count) {
base.Write(buffer, offset, count);
bytesWritten += count;
}
public override void WriteByte(byte value) {
bytesWritten += 1;
base.WriteByte(value);
}
}
然后你可以像这样使用它:
BinaryFormatter bf = new BinaryFormatter();
var s = new MyStream();
bf.Serialize(s, new DateTime[200]);
这将在写入字节时为您提供字节,因此您可以使用它计算时间。注意:您可能需要重写stream类的其他几个方法 哇。你把这么大的东西序列化,以至于你可以在墙上的时钟上计时?你在做XML序列化吗?嗯,是的,我的一些可序列化的东西可能需要1分钟,这是二进制序列化:只有很多对象……序列化时对象有多大?当集合包含1066个不同大小的对象时,平均为9Mbs,序列化大约需要10秒。另一个例子-19 Mbs和大约30秒用于序列化,而集合中有很多没有意义的对象。那很小。你在做什么,而不是BinaryFormatter.Serialize?哇。你把这么大的东西序列化,以至于你可以在墙上的时钟上计时?你在做XML序列化吗?嗯,是的,我的一些可序列化的东西可能需要1分钟,这是二进制序列化:只有很多对象……序列化时对象有多大?当集合包含1066个不同大小的对象时,平均为9Mbs,序列化大约需要10秒。另一个例子-19 Mbs和大约30秒用于序列化,而集合中有很多没有意义的对象。那很小。你在做BinaryFormatter.Serialize之外的事情吗?我希望还有其他事情可以做,请稍等,直到将此标记为已接受:P Thank我希望还有其他事情可以做,请稍等,直到将此标记为已接受:P Thanks但我可以通过哪种方式知道传输了多少字节?好的,我不知道你是怎么序列化数据的。但是,通常在特定的块对象中完成,当每个块被序列化时,如果需要,使用Thread.VolatileWrite更新字段ByTestTransferred。但是我可以通过哪种方式知道传输了多少字节?我不知道您是如何序列化数据的。但是,通常在特定的chunk对象中完成,当每个chunk被序列化时,如果需要,使用Thread.VolatileWrite更新字段ByTestTransferred。如果这样做有效,我认为这就是解决方案!我可以以静态成员的身份编写BytesWrite,这样我就可以读取另一个线程MyStream中写入了多少内容。BytesWrite也会更新ProgressBarWell,我不会使用静态。我将公开一个您可以订阅的BytesWrite事件,这样您就可以在同一进程中同时序列化多个对象,但这是另一个问题:如果这是可行的,我想这就是解决办法!我可以以静态成员的身份编写BytesWrite,这样我就可以读取另一个线程MyStream中写入了多少内容。BytesWrite也会更新ProgressBarWell,我不会使用静态。我将公开一个您可以订阅的BytesWrited事件,这样您可以同时在同一进程中序列化多个对象,但这是另一个问题。 :