/// <summary>
 /// 当主窗口点击停止任务后, 改变任务状态
 /// </summary>
 private void ChangeTaskStatus()
 {
     //发送提示文本
     OnTaskBarEvent?.Invoke(new MainWindowStatusNotify
     {
         alertLevel  = AlertLevel.RUN,
         nowProgress = 99,
         message     = "正在停止.."
     });
     if (mSyncFileBgWorker.IsBusy)
     {
         mSyncFileBgWorker.CancelAsync();
     }
     while (mSyncTaskQueue.Count > 0)
     {
         var item = new DeviceSyncTaskArgs();
         _ = mSyncTaskQueue.TryDequeue(out item);
     }
     if (mReadDeviceFileWorker.IsBusy)
     {
         mReadDeviceFileWorker.CancelAsync();
     }
 }
        /// <summary>
        /// 点击同步按钮事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void OnSyncButtonClick(object sender, RoutedEventArgs e)
        {
            Button button = sender as Button;

            button.IsEnabled = false;
            var selected = (DeviceSyncListViewModel)((ListViewItem)DeviceSyncListView.ContainerFromElement(button)).Content;
            var taskArgs = new DeviceSyncTaskArgs
            {
                ThatButton = button,
                Item       = selected,
                Device     = DeviceListCombobox.SelectedItem as MediaDevice,
                DevicePath = ((DeviceDriverViewModel)DriverListCombobox.SelectedItem).ValueView
            };

            //将任务添加进队列
            mSyncTaskQueue.Enqueue(taskArgs);
            if (mSyncFileBgWorker.IsBusy)
            {
                //任务正在运行则直接返回
                return;
            }
            //如果任务没有运行, 则开启一个任务
            mSyncFileBgWorker.RunWorkerAsync();
        }
        /// <summary>
        /// 执行同步文件的后台任务
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DoSyncFileTask(object sender, DoWorkEventArgs e)
        {
            var winProgress = new MainWindowStatusNotify()
            {
                alertLevel       = AlertLevel.RUN,
                animateProgress  = true,
                progressDuration = 100,
                nowProgress      = 0
            };
            var isTaskStop = false;
            //当前执行的队列编号
            var curTaskNo = 1;
            //当前队列最大元素数量
            var maxedQueueCount = mSyncTaskQueue.Count;

            while (mSyncTaskQueue.Count > 0)
            {
                var arg    = new DeviceSyncTaskArgs();
                var isPick = mSyncTaskQueue.TryDequeue(out arg);
                if (!isPick)
                {
                    continue;
                }
                //每个队列的分片进度
                double eachBaseProgress = 0;
                //筛选WPD设备
                using (var device = arg.Device)
                {
                    device.Connect();

                    //检查目标文件夹是否存在, 不存在则创建
                    if (!Directory.Exists(arg.Item.PcFolderNameView))
                    {
                        FileUtil.CreateFolder(arg.Item.PcFolderNameView);
                    }
                    var targetMobileFolder = Path.Combine(arg.DevicePath, arg.Item.MobileFolderNameView);
                    if (!device.DirectoryExists(targetMobileFolder))
                    {
                        device.CreateDirectory(targetMobileFolder);
                    }

                    //将两端的文件合并到一个集合
                    var allItems = arg.Item.PcItemList.ToList();
                    allItems.AddRange(arg.Item.MobileItemList.ToList());
                    var fileCounter = 1;
                    allItems.ForEach((syncFile) => {
                        //检查任务是否取消
                        if (mSyncFileBgWorker.CancellationPending)
                        {
                            isTaskStop = true;
                            return;
                        }
                        //如果队列数量增大超过初始量, 记录一个最大数量
                        if (mSyncTaskQueue.Count + 1 > maxedQueueCount)
                        {
                            maxedQueueCount = mSyncTaskQueue.Count + 1;
                        }
                        //当前队列数量=此队列拥有过的最大数量
                        var curQueueCount = maxedQueueCount;
                        //计算每个队列的分片进度
                        eachBaseProgress = 100 / curQueueCount;
                        //每个队列的基础进度, 从0开始, 以分片进度递增
                        double baseProgress = 100 - (mSyncTaskQueue.Count + 1) * eachBaseProgress;
                        //计算每个文件的分片进度
                        double eachFileProgress = eachBaseProgress / allItems.Count;
                        //文件的执行进度, 从0开始递增
                        double fileProgress = eachFileProgress * fileCounter - eachFileProgress;
                        //总进度 = 基础进度 + 文件进度
                        WindowUtil.CalcProgress(winProgress,
                                                string.Format("主任务 [{0}/{1}], 子任务 [{2}/{3}], 正在复制 [ {4} ]", curTaskNo, curQueueCount, fileCounter, allItems.Count, syncFile.NameView),
                                                baseProgress + fileProgress);
                        arg.Progress     = winProgress;
                        arg.ProgressType = SyncTaskProgressType.SUB_ITEM_FINISH;
                        mSyncFileBgWorker.ReportProgress(0, arg);
                        //执行同步
                        if (syncFile.SourceView == SyncDeviceType.PC)
                        {
                            //电脑端, 需要复制到移动端
                            var targetFolder = Path.Combine(arg.DevicePath, arg.Item.MobileFolderNameView);
                            using (FileStream stream = System.IO.File.OpenRead(Path.Combine(arg.Item.PcFolderNameView, syncFile.NameView)))
                            {
                                device.UploadFile(stream, Path.Combine(targetFolder, syncFile.NameView));
                            }
                        }
                        else
                        {
                            MediaFileInfo fileInfo = device.GetFileInfo(Path.Combine(arg.DevicePath, arg.Item.MobileFolderNameView, syncFile.NameView));
                            fileInfo.CopyTo(Path.Combine(arg.Item.PcFolderNameView, syncFile.NameView));
                        }
                        fileProgress = eachFileProgress * fileCounter;
                        WindowUtil.CalcProgress(winProgress,
                                                string.Format("主任务 [{0}/{1}], 子任务 [{2}/{3}], 正在复制 [ {4} ]", curTaskNo, curQueueCount, fileCounter, allItems.Count, syncFile.NameView),
                                                baseProgress + fileProgress);
                        arg.Source         = syncFile.SourceView;
                        arg.DeviceSyncItem = syncFile;
                        mSyncFileBgWorker.ReportProgress(0, arg);
                        fileCounter++;
                    });
                    device.Disconnect();
                }
                arg.IsOk         = !isTaskStop;
                arg.ProgressType = SyncTaskProgressType.QUEUE_FINISH;
                if (!isTaskStop)
                {
                    //一个队列执行完之后, 发送当前队列进度
                    WindowUtil.CalcProgress(arg.Progress, string.Format("主任务 [{0}/{1}]同步完成", curTaskNo, maxedQueueCount), curTaskNo * eachBaseProgress);
                    mSyncFileBgWorker.ReportProgress(0, arg);
                    curTaskNo++;
                }
                else
                {
                    mSyncFileBgWorker.ReportProgress(0, arg);
                }
            }
            e.Result = !isTaskStop;
        }