[英]how to fix form lagging when its labels changes by a thread?
my application sends file to server using (socket tcp c#) 我的应用程序使用(socket tcp c#)将文件发送到服务器
the file transfer works perfectly .. but progress form that shows me the progress of sending doesn't work well 文件传输可以正常工作..但是向我显示发送进度的进度表无法正常工作
its lagging and shows like 45mb/s then 2mb/s it continually goes up and down and when i try to move the window it lags a little like there's something wrong in the thread .. i hope you understand what's happening .. 它滞后并显示为45mb / s,然后显示为2mb / s,它不断地上下移动,当我尝试移动窗口时,它滞后一些,就像线程中有什么问题..我希望您了解正在发生的事情..
how to fix that ? 如何解决?
Thread thS = new Thread(timeElasped);
thS.Start(); //this code runs when the form show up
the code below executes by a thread in the progress Form 下面的代码由进度表中的线程执行
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);
}
}
this's the code of sending the file 这是发送文件的代码
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));
}
}
If your form appears to be "blocked" for a while, then you probably have a bad design as your UI thread does blocking job. 如果您的表单似乎被“阻塞”了一段时间,那么您的设计可能很糟糕,因为您的UI线程确实阻塞了工作。
Here is a simple but complete example of a worker thread and a notified form that ensures UI responsiveness: 这是一个简单但完整的工作线程示例和可确保UI响应性的通知表单:
Form: 形成:
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 class: 工人阶级:
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 });
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.