2012-01-26 18 views
1

我的應用程序發送文件到服務器使用(套接字tcp c#)
文件傳輸完美..但進度形式,顯示我的發送進度不太好
其滯後和顯示像45mb/s然後2mb /它不斷上升和下降,當我試圖移動窗口它滯後有點像線程中有什麼問題.. 我希望你明白髮生了什麼..
如何解決這個問題?如何解決當標籤由線程變化時形式滯後?

Thread thS = new Thread(timeElasped); 
thS.Start(); //this code runs when the form show up 

下面的代碼通過一個線程在進度表執行

private void timeElasped() 
    { 
     int counter = 0; 
     while (fileTransfer.busy) 
     { 
      rate = (fileTransfer.sum - prevSum); 
      RateLabel(string.Format("{0}/Sec", CnvrtUnit(rate))); 
      if(rate!=0) 
       left = (fileTransfer.fileSize - fileTransfer.sum)/rate; 
      prevSum = fileTransfer.sum; 
      TimeSpan t = TimeSpan.FromSeconds(left); 
      timeLeftLabel(FormatRemainingText(rate, t)); 
      TimeSpan Duration = TimeSpan.FromSeconds(counter); 
      ElapsedLabel(string.Format("{0:D2}:{1:D2}:{2:D2}", Duration.Hours, Duration.Minutes, Duration.Seconds)); 
      counter++; 
      Thread.Sleep(1000); 
     } 
    } 

這是發送文件

public static void sendFile(string filePath) 
    { 
     //initialize a thread for progress form 
     Thread thFP = new Thread(fpRUN); 
     FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read); 
     string fileName = Path.GetFileName(filePath); 
     byte[] fileData; 
     try 
     { 
      //sending file name and file size to the server 
      busy = true; 
      fileSize = fs.Length; 
      byte[] fileDetial = null; 
      string detail = fileName + "," + fileSize.ToString(); 
      fileDetial = Encoding.ASCII.GetBytes(detail); 
      client.Send(fileDetial); 

      //sending file data to the server 

      fileData = new byte[packetSize]; 
      count = 0; 
      sum = 0;       
      // running transfer rate 
      fileProgress fP = new fileProgress("Sending..."); 
      //show the progress form 
      thFP.Start(fP); 

      while (sum < fileSize) 
      { 
       fP.ProgressBarFileHandler(sum, fileSize); 
       fs.Seek(sum, SeekOrigin.Begin); 
       fs.Read(fileData, 0, fileData.Length); 
       count = client.Send(fileData, 0, fileData.Length, SocketFlags.None); 
       sum += count; 
      } 
     } 
     finally 
     { 
      busy = false; 
      fs.Close(); 
      fileData = null; 
      MessageBox.Show(string.Format("{0} sent successfully", fileName)); 
     } 
    } 
+1

你說說有一個表單的問題,但很少有證據表明這個表單是如何在代碼片段中使用的。任何調用Thread.Sleep(1000)的代碼都很慢。廢棄這個並使用BackgroundWorker。 –

回答

0

的代碼,如果你的形式似乎是「封殺」了而當你的UI線程阻塞工作時,你可能會有一個糟糕的設計。

這裏是工作線程的一個簡單但完整的實例和通知的形式,確保用戶界面的響應:

形式:

public partial class Form1 : Form 
{ 
    private Worker worker; 

    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     worker = new Worker(); 
     worker.ProgressUpdated += this.worker_ProgressUpdated; 
     worker.WorkDone += this.worker_WorkDone; 
     worker.Start(); 
    } 

    private void worker_WorkDone(object sender, EventArgs e) 
    { 
     // Detaches event handlers 
     // /!\ Will be called from a thread different than the UI thread 
     worker.ProgressUpdated -= this.worker_ProgressUpdated; 
     worker.WorkDone -= this.worker_WorkDone; 
    } 

    private void worker_ProgressUpdated(object sender, ProgressEventArgs e) 
    { 
     // Updates the UI 
     // /!\ Will be called from a thread different than the UI thread 
     this.SetLabelText(string.Format("Percentage: {0}", ((double)e.Value * 100/(e.Max - e.Min)))); 
    } 

    private void SetLabelText(string text) 
    { 
     // Following required if the method is called from a thread that is not the UI thread 
     if (this.label1.InvokeRequired) 
     { 
      this.label1.Invoke(new MethodInvoker(() => this.SetLabelText(text))); 
     } 
     else 
     { 
      this.label1.Text = text; 
     } 
    } 
} 

Worker類:​​

public class ProgressEventArgs : EventArgs 
{ 
    public int Value { get; set; } 

    public int Max { get; set; } 

    public int Min { get; set; } 
} 

public class Worker 
{ 
    public delegate void ProgressUpdatedEventHandler(object sender, ProgressEventArgs e); 

    public event ProgressUpdatedEventHandler ProgressUpdated; 

    public event EventHandler WorkDone; 

    public void Start() 
    { 
     Thread workerThread = new Thread(new ThreadStart(this.DoWork)); 
     workerThread.Start(); 
    } 

    private void DoWork() 
    { 
     int min = 0; 
     int max = 1000000; 

     for (int i = min; i < max; i++) 
     { 
      // Simulates work 
      ////System.Threading.Thread.Sleep(1); 

      // Notify of progress update 
      ////this.OnProgressUpdate(min, max, i); 

      // Notify of progress update but not every time to save CPU time 
      // Uses mod function to do the job 1 out of 100 times 
      if (i % 100 == 0) 
      { 
       this.OnProgressUpdate(min, max, i); 
      } 
     } 

     // Notify the work is done 
     if (this.WorkDone != null) 
     { 
      this.WorkDone(this, EventArgs.Empty); 
     } 
    } 

    private void OnProgressUpdate(int min, int max, int value) 
    { 
     if (this.ProgressUpdated != null) 
     { 
      this.ProgressUpdated(this, new ProgressEventArgs { Max = max, Min = min, Value = value }); 
     } 
    } 
} 
+0

我想這是偉大的我沒有使用我的工人班,但我用backgroundworker –