none
FileStream异步读写文件,CPU超高! RRS feed

  • 问题

  • 如图,WPF的DataGrid中添加了DataGridTemplateColumn,用于展示远程服务器的文件,点开始按钮后开始获取文件并下载到本地。

    每个下载任务中采用异步Task,过程中发现开启单个或多个下载任务时都会占用CPU很高,如何优化?

    后台:

    public ObservableCollection<FileInfo> fileInfoCollection = new ObservableCollection<FileInfo>();
    public void StartDownLoad(string sourceFilePath, string localFilePath, int fileIndex)
            {
                if (!fileInfoCollection[fileIndex].IsStart)
                {
                    Task.Run( async () => { await DwonLoadFile(sourceFilePath, localFilePath, fileIndex); });
                }
            }
     private async Task DwonLoadFile(string sourceFilePath, string localFilePath, int fileIndex)
            {
                if (!File.Exists(sourceFilePath))
                    return;
                WebRequest request = WebRequest.Create(sourceFilePath);
                WebResponse response = await request.GetResponseAsync();
                Stream netStream = response.GetResponseStream();
                Stream fileStream = new FileStream(localFilePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
                fileStream.Position = 0;
                byte[] read = new byte[1024];
                long progressBarValue = 0;
                int realReadLen = await netStream.ReadAsync(read, 0, read.Length);
                Thread thread = new Thread(new ThreadStart(async delegate
                {
                    while (realReadLen > 0 && !fileInfoCollection[fileIndex].IsStopped)
                                {
                        if (fileInfoCollection[fileIndex].IsSuspend == false)
                                    {
                            await fileStream.WriteAsync(read, 0, realReadLen);
                            progressBarValue += realReadLen;
                            double len = double.Parse((progressBarValue / 1024.00 / 1024.00).ToString("F2"));
    fileInfoCollection[fileIndex].CompletePercentage = Math.Ceiling(((double)progressBarValue / (double)netStream.Length) * 100) + "%";
                            fileInfoCollection[fileIndex].CompletedProgress = len;
                            fileInfoCollection[fileIndex].ProgressBarValue = progressBarValue;
                            realReadLen = await netStream.ReadAsync(read, 0, read.Length);
                            continue;
                        }
                        Thread.Sleep(1);
                                }
                    netStream.Close();
                    fileStream.Close();
                }));
                thread.IsBackground = true;
                thread.Start();
            }       

    前台:

    private void SuspendOrStartBtn_Click(object sender, RoutedEventArgs e)
            {
                FileInfo item = ((Button)sender).DataContext as FileInfo;
                int index = FileDataGrid.Items.IndexOf(item);
    
                //开始任务
                if (fileManager.fileInfoCollection[index].IsSuspend==true)
                {
                    fileManager.StartDownLoad(item.SourceFileFullName, @"D:\" + item.SourceFileName, index);
                    fileManager.fileInfoCollection[index].IsStart = true;
                    fileManager.fileInfoCollection[index].IsSuspend = false;
                    SetPauseResumeButtonText(index);
                }
                else//暂停任务
                {
                    fileManager.fileInfoCollection[index].IsSuspend = true;
                    SetPauseResumeButtonText(index);
                }
                
            }

    2018年7月20日 3:42

答案

  • Hi 银光海阁,

    一般情况下, 如果你使用异步下载文件, 他会自动检测到您当前可以使用的CPU, 然后尽可能的使用你剩余的CPU. 如果你觉得此操作占用CPU太高, 您可以考虑设置FileStream的Buffer来限流,这可能回降低当前文件下载所使用的CPU。

    Best Regards,

    Cherry


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2018年7月23日 8:29
    版主
  • 新创建的Task的数量应该与CPU的核数相当,比如有20个file download task,CPU 4核,则应该将task拆分为5个一组,只创建4个task。


    专注于.NET ERP/CRM开发框架,C/S架构,SQL Server + ORM(LLBL Gen Pro) + Infragistics WinForms

    2018年7月24日 0:29

全部回复

  • Hi 银光海阁,

    一般情况下, 如果你使用异步下载文件, 他会自动检测到您当前可以使用的CPU, 然后尽可能的使用你剩余的CPU. 如果你觉得此操作占用CPU太高, 您可以考虑设置FileStream的Buffer来限流,这可能回降低当前文件下载所使用的CPU。

    Best Regards,

    Cherry


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    2018年7月23日 8:29
    版主
  • 新创建的Task的数量应该与CPU的核数相当,比如有20个file download task,CPU 4核,则应该将task拆分为5个一组,只创建4个task。


    专注于.NET ERP/CRM开发框架,C/S架构,SQL Server + ORM(LLBL Gen Pro) + Infragistics WinForms

    2018年7月24日 0:29
  • Hi 银光海阁,

    一般情况下, 如果你使用异步下载文件, 他会自动检测到您当前可以使用的CPU, 然后尽可能的使用你剩余的CPU. 如果你觉得此操作占用CPU太高, 您可以考虑设置FileStream的Buffer来限流,这可能回降低当前文件下载所使用的CPU。

    Best Regards,

    Cherry


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    这种方案我验证过,但效果甚微,会导致每个Task任务在下载过程中有卡顿,就是因为“节流”的缘故。

    感谢回复!

    2018年7月24日 1:30