C#传输大文件如何保证界面不卡死啊

我用文件流传输1G以上大小的大文件,传输过程不用Application.DoEvents(),如何让界面不卡死,用的winform,用await和async还是会卡

引用 皆我百晓生 小程序回复内容作答:
在传输大文件时,为了保证界面不会卡死,可以考虑使用异步操作。在C#中,可以使用asyncawait关键字来实现异步操作。

以下是一个示例的代码:

private async Task TransferFileAsync(string sourceFilePath, string destinationFilePath)
{
    using (FileStream sourceFileStream = new FileStream(sourceFilePath, FileMode.Open))
    using (FileStream destinationFileStream = new FileStream(destinationFilePath, FileMode.Create))
    {
        byte[] buffer = new byte[4096];
        int bytesRead;

        while ((bytesRead = await sourceFileStream.ReadAsync(buffer, 0, buffer.Length)) > 0)
        {
            await destinationFileStream.WriteAsync(buffer, 0, bytesRead);
            // 更新UI进度条等界面操作可以放在这里
        }
    }
}

在调用该方法时,可以使用await来等待传输完成:

await TransferFileAsync(sourceFilePath, destinationFilePath);

通过使用异步操作,传输大文件的过程将会在后台线程进行,而不会阻塞主线程,从而保证界面的响应性。

注意,你还可以在传输过程中,使用事件或委托进行进度更新等界面操作,而不需要使用Application.DoEvents()

上传文件跟“Application.DoEvents()”没有必然联系

除非你想带进度,或者跟着某园子写成一个“while(true)” 一次写1024字节。

如果是上传文件还想带进度,建议用“IProcess” 进行进度通知

分析完毕,我也不想写代码,直接问chartgpt好了
“C# httpclient 异步上传文件 使用IProcess 在UI上实时显示进度”

chartgpt的回答(我不保证chartgpt 代码正确,只是告诉你我们的思路以及最后可能的代码实现)

public async Task UploadFileWithProgressAsync(string filePath, Uri uploadUri, IProgress<double> progress)
{
    var progressHandler = new ProgressMessageHandler();

    // Subscribe to the progress event
    progressHandler.HttpSendProgress += (sender, args) =>
    {
        if (args.TotalBytes == 0) return; // To avoid division by zero

        double percentComplete = (double)args.BytesTransferred / args.TotalBytes * 100.0;
        progress.Report(percentComplete);
    };

    using (var httpClient = new HttpClient(progressHandler))
    using (var fileStream = File.OpenRead(filePath))
    using (var content = new MultipartFormDataContent())
    {
        var fileContent = new StreamContent(fileStream);
        fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
        {
            Name = "file",
            FileName = Path.GetFileName(filePath)
        };

        content.Add(fileContent);

        var response = await httpClient.PostAsync(uploadUri, content);

        // Handle the response as needed
    }
}

调用层

var progress = new Progress<double>(percent => {
    //注意这里可能有跨进程操作,如何处理你自己来,你是invoke,还是用上下文同步,你看情况弄
    progressBar.Value = percent;
});

await UploadFileWithProgressAsync("path_to_file", yourUploadUri, progress);

发现是任务里用了同步模型里的上下文造成了卡顿