C# 当标签被线程更改时,如何修复窗体滞后?
我的应用程序使用(套接字tcp c#)将文件发送到服务器C# 当标签被线程更改时,如何修复窗体滞后?,c#,multithreading,forms,lag,C#,Multithreading,Forms,Lag,我的应用程序使用(套接字tcp c#)将文件发送到服务器文件传输工作正常。。但是向我显示发送进度的进度表不起作用 它的滞后显示为45mb/s,然后是2mb/s,它不断地上下移动,当我尝试移动窗口时,它有点滞后,好像线程中有什么问题。。 我希望你明白发生了什么事。如何解决 Thread thS = new Thread(timeElasped); thS.Start(); //this code runs when the form show up 下面的代码由进度表单中的线程执行
文件传输工作正常。。但是向我显示发送进度的进度表不起作用
它的滞后显示为45mb/s,然后是2mb/s,它不断地上下移动,当我尝试移动窗口时,它有点滞后,好像线程中有什么问题。。 我希望你明白发生了什么事。
如何解决
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));
}
}
publicstaticvoidsendfile(字符串文件路径)
{
//初始化进程窗体的线程
线程thFP=新线程(fpRUN);
FileStream fs=newfilestream(filePath,FileMode.Open,FileAccess.Read);
字符串fileName=Path.GetFileName(filePath);
字节[]文件数据;
尝试
{
//将文件名和文件大小发送到服务器
忙=真;
fileSize=fs.Length;
字节[]fileDetial=null;
字符串详细信息=fileName+“,“+fileSize.ToString();
fileDetial=Encoding.ASCII.GetBytes(详细信息);
client.Send(fileDetial);
//将文件数据发送到服务器
fileData=新字节[packetSize];
计数=0;
总和=0;
//运行传输速率
fileProgress fP=新文件进度(“发送…”);
//显示进度表
thFP.启动(fP);
while(总和<文件大小)
{
fP.ProgressBarFileHandler(总和,文件大小);
Seek(sum,SeekOrigin.Begin);
fs.Read(fileData,0,fileData.Length);
count=client.Send(fileData,0,fileData.Length,SocketFlags.None);
总和+=计数;
}
}
最后
{
忙=假;
fs.Close();
fileData=null;
Show(string.Format(“{0}发送成功”,文件名));
}
}
如果您的表单在一段时间内似乎被“阻止”,那么您的UI线程执行阻止任务时,您的设计可能很糟糕
下面是一个简单但完整的工作线程示例和一个确保UI响应的通知表单:
表格:
工人阶级:
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 });
}
}
}
公共类ProgressEventArgs:EventArgs
{
公共int值{get;set;}
公共int Max{get;set;}
公共int Min{get;set;}
}
公社工人
{
公共委托void ProgressUpdatedEventHandler(对象发送方,ProgressEventArgs e);
公共事件进度更新事件进度更新;
公共事件处理程序1;
公开作废开始()
{
Thread workerThread=新线程(新线程开始(this.DoWork));
workerThread.Start();
}
私房
{
int min=0;
int max=1000000;
对于(int i=min;i
您谈到表单有问题,但很少有证据表明该表单是如何在代码段中使用的。任何调用Thread.Sleep(1000)的代码都很慢。放弃这个,使用BackgroundWorker。我想这很好,我没有使用你的工人类,但我使用BackgroundWorker
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 });
}
}
}