سؤال

I use C# .net 4.0 and don't see any possible way to do it, but maybe you know? :)
I do my serialization in that way:

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));
    }
}
هل كانت مفيدة؟

المحلول

So, let's say you use actually know in advance the size of your object graph, which itself may be difficult, but let's just assume you do :). You could do this:

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

Then you could use it like:

BinaryFormatter bf = new BinaryFormatter();
var s = new MyStream();
bf.Serialize(s, new DateTime[200]);

This will give you the bytes as they are written, so you could calculate the time using that. Note: it's possible you might need to override a few more methods of the stream class.

نصائح أخرى

I don't believe there is. My advice would be to time how long it takes to serialize (repeating the measurement several hundred or thousand times), average them, and then use that as a constant for calculating serialization progress.

You could start a timer that runs at a specific frequency (say 4 times a second, but that really has no bearing on anything but how frequently you want to update progress) that calculates how long data currently has taken to transfer, then estimate the remaining time. For example:

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 assumes you're updating this.bytesTransferred on another thread and you're targeting AnyCPU.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top