在 C# 中达到 100% 后更新进度条

progress bar is updated after reaching 100% in c#

我正在研究文件传输软件。但是进度条直接显示100%,不显示实际进度。所以我需要改变我的方法来写文件。或者有一些愚蠢的错误。这是我的代码。 Form1.cs

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Media;
using System.Threading;

namespace Sender2
{

public partial class Form1 : Form
{
    private Thread thrDownload;
    private static int PercentProgress;
    private delegate void UpdateProgessCallback(Int64 BytesRead, Int64 TotalBytes);

    public Form1()
    {
        InitializeComponent();
    }

    private void Browse_Click(object sender, EventArgs e)
    {
        if (openFileDialog1.ShowDialog() == DialogResult.OK)
        {
            txtSelectFilePath.Text = openFileDialog1.FileName;
            String path1=txtSelectFilePath.Text;
            files_list.Items.Add(path1);
            files_list.View = View.List;

        }
    }

    private void UpdateProgress(Int64 BytesRead, Int64 TotalBytes)
    {

        PercentProgress = Convert.ToInt32((BytesRead * 100) / TotalBytes);

        progressBar1.Value = PercentProgress;

        lblProgress.Text = "Downloaded " + BytesRead + " out of " + TotalBytes + " (" + PercentProgress + "%)";
    }


    private void Send_Click(object sender, EventArgs e)
    {
        TransferService2.TransferService2Client client = new TransferService2.TransferService2Client();

        foreach(ListViewItem item in files_list.Items)
        {
            TransferService2.File file = client.DownloadDocument(item.Text);
            System.IO.FileStream fs = new System.IO.FileStream(@"c:\DownloadedFiles\" + file.Name, System.IO.FileMode.Create); 
Int64 fileSize = file.Content.Length;
            int bytesSize = 0;
            byte[] downBuffer = new byte[2048];
            int pos = 0;
            int length = 128;
            while (pos < file.Content.Length)
            {
                if (length > (file.Content.Length - pos))
                {
                    length = file.Content.Length - pos;
                } 
                fs.Write(file.Content, pos, length); 
                this.Invoke(new UpdateProgessCallback(this.UpdateProgress), new object[] { file.Content.Length, fileSize });
                pos = pos + length;
            }
            MessageBox.Show(file.Name + " is downloaded");

        }

    }






}
}

TransferService2.cs

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace TransferService2
{
public class TransferService2 : ITransferService2
{

    public File DownloadDocument(String filepath)
    {
        File file = new File();
        String path = filepath; 
        byte[] buffer;
        FileStream fs = new FileStream(@path, FileMode.Open, FileAccess.Read);
        try
        {
            int length = (int)fs.Length;
            buffer = new byte[length];
            int count;
            int sum = 0;
            while((count=fs.Read(buffer,sum,length-sum))>0)
            {
                sum = sum + count;
            } 
        }
        finally
        {
            fs.Close();
        }
        file.Content = buffer; 
        file.Name = Path.GetFileName(path);
        return file;
    }
}
}

我TransferService2.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;

namespace TransferService2
{

[ServiceContract]
public interface ITransferService2
{
    [OperationContract]
    File DownloadDocument(String filepath);
}

[DataContract]
public class File
{
    [DataMember]
    public string Name { get; set; }

    [DataMember]
    public byte[] Content { get; set; }

}
}

正如我在评论中提到的,您正在 UI 线程上同步执行整个操作,因此它很忙并且在处理期间无法更新。

您需要让操作异步执行。有很多方法可以做到这一点,这是使用 async/await:

的一种可能方法
private async void Send_Click(object sender, EventArgs e)
{

    TransferService2.TransferService2Client client = new TransferService2.TransferService2Client();

    foreach(ListViewItem item in files_list.Items)
    {
        TransferService2.File file = await Task.Run(() => client.DownloadDocument(item.Text));
        System.IO.FileStream fs = new System.IO.FileStream(@"c:\DownloadedFiles\" + file.Name, System.IO.FileMode.Create); 
        Int64 fileSize = file.Content.Length;
        int bytesSize = 0;
        byte[] downBuffer = new byte[2048];
        int pos = 0;
        int length = 128;
        while (pos < file.Content.Length)
        {
            if (length > (file.Content.Length - pos))
            {
                length = file.Content.Length - pos;
            } 
            await fs.WriteAsync(file.Content, pos, length);
            // Here the await will resume on the UI thread, so no Invoke is needed
            pos = pos + length;
            this.UpdateProgress(pos, fileSize);
        }
        MessageBox.Show(file.Name + " is downloaded");
    }
}