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 下面的代码由进度表单中的线程执行

我的应用程序使用(套接字tcp c#)将文件发送到服务器
文件传输工作正常。。但是向我显示发送进度的进度表不起作用
它的滞后显示为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 });
        }
    }
}