简体   繁体   English

当标签的标签被线程改变时,如何解决表格滞后的问题?

[英]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.

相关问题 如何修复Android版本的高速和滞后 - How to fix high speed and lagging on Android build 当添加到Form.Controls时,RadioButton更改其高度。 - RadioButton changes its Height when addeed to Form.Controls 为什么TextBox仅在使用Thread.sleep()暂停时才更改其值? - Why TextBox changes its value only when a pause with Thread.sleep() it is used? 我是否应该确保在主循环期间某个值在其范围内,还是应该在该值更改时对其进行修复? - Should I just make sure a value is within its range during a main loop or fix it when it supposedly changes? 如何在WinRT XAML中更改其值时为TextBlock设置动画? - How to animate TextBlock when its value changes in WinRT XAML? 是否可以将窗体控件放在其自己的线程上? - Is it possible to put a form control on its own thread? 如何解决未在ListViews中显示的标签? - How to fix labels not showing up in ListViews? 如何在 C# Windows 窗体应用程序中修复窗体大小而不让用户更改其大小? - How can I fix the form size in a C# Windows Forms application and not to let user change its size? 当另一个输入更改时,如何更新表单输入? - How to update a form input when another input changes? 当类中的属性更改时,如何在表单中接收属性更改的通知? - How to receive property changed notifications in a Form when a property changes in a class?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM