2012-08-24 3 views
1

나는 C# .net 4.0을 사용하고 그것을 할 수있는 어떤 방법도 보이지 않지만 어쩌면 알 수 있을까? :)
내가 그런 식으로 내 직렬화를 수행합니다 나는 생각하지 않는다ProgressBar에 표시하기 위해 직렬화 시간을 계산하거나 얻는 방법이 있습니까?

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

와우. 벽 시계에서 실제로 시간을 측정 할 수 있도록 너무 큰 것을 직렬화하고 있습니까? XML 직렬화 작업을하고 있습니까? – aquinas

+0

ehm 예, 직렬화 가능한 것들 중 일부는 최대 1 분이 걸릴 수 있습니다. 이것은 바이너리 직렬화입니다 :) 단지 많은 객체가 있습니다. – Kosmos

+0

직렬화 될 때 객체의 크기는 얼마나됩니까? (평균적으로) – aquinas

답변

2

그래서 실제로 미리 알고있는 개체 그래프의 크기를 알고 있다고 가정 해 봅시다. 그 자체로는 어려울 수도 있지만 실제로는 가정합니다. 이 작업을 수행 할 수 있습니다 :

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

이 당신에게 바이트를 제공 할 것입니다. 참고 : 스트림 클래스의 몇 가지 메서드를 재정의해야 할 수도 있습니다.

+0

이것이 작동한다면, 이것이 해결책이라고 생각합니다! 정적 멤버로 bytesWritten 할 수있는, 그래서 얼마나 많은 다른 스레드 (MyStream.bytesWritten) 또한 업데이트 ProgressBar 쓸 수 있습니다. – Kosmos

+0

글쎄, 정적 사용하지 않을. 같은 프로세스에서 여러 객체를 동시에 직렬화 할 수있는 방식으로 구독 할 수있는 BytesWritten 이벤트를 노출합니다.하지만 다른 질문에 대한 것입니다. :) – aquinas

+0

이벤트도 좋은 해결책입니다 :) 감사합니다! – Kosmos

1

이있다. 내 충고는 직렬화 (측정을 수백 번 또는 수천 번 반복)하고 평균화 한 다음 직렬화 진행 상황을 계산하는 데 상수로 사용하는 데 걸리는 시간을 측정하는 것입니다.

+0

다른 일이있을 수 있기를 바래요, 받아 들일 때까지 조금 기다릴 것입니다 : P 덕분 – Kosmos

1

특정 주파수 (예 : 초당 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.bytesTransferred을 업데이트하고 당신이 anycpu를 타겟팅하는 가정 예를 들면 다음과 같습니다.

+0

고마워요하지만 어느 정도 바이트를 전송할 수 있습니다 알 수 있습니까? – Kosmos

+0

음, 데이터를 직렬화하는 방법 *을 알지 못합니다. 그러나 일반적으로 각 청크가 직렬화 될 때 특정 청크 (객체)에서 수행되는 작업은 필요한 경우 'Thread.VolatileWrite'로 필드 'bytesTransferred'를 업데이트합니다. –

관련 문제