/// <summary>
        /// 既に開始している変換が終わるまで待機する
        /// </summary>
        /// <param name="mutex"></param>
        /// <returns></returns>
        private async Task <bool> WaitingPreviosConvert(MutexWrapper mutex)
        {
            int waitCount = 0;

            while (true)
            {
                if (IsCancellationRequested || IsCancellationNextRequested)
                {
                    return(false);
                }
                bool createdNew;
                try
                {
                    createdNew = await mutex.WaitOne(Constant.MutexWaitIntervalMiliSecond, false);
                }
                catch (AbandonedMutexException)
                {
                    createdNew = true;
                }
                waitCount++;

                if (createdNew)
                {
                    return(true);
                }
                else if (waitCount * Constant.MutexWaitIntervalMiliSecond > Constant.MutexWaitMaxMiliSecond)
                {
                    LogWindow.LogMessage($"変換完了待受の最大実効時間をオーバーしました。中断します。 runTime={waitCount}", LogWindow.MessageType.Error);
                    return(false);
                }
                else
                {
                    OnConvertStateChanged(0, 0, $"0/{SourceFileList.Count}", $"Wait {Math.Round((double)waitCount / 60, 0)}min");
                }
            }
        }
        /// <summary>
        /// 複数のファイルをバッチで変換実行する
        /// </summary>
        /// <returns>非同期タスク</returns>
        public async Task BatchConvert()
        {
            using (var mutex = new MutexWrapper(false, "HandBrakeBatchRunner"))
            {
                // 既に実行中の場合は待機する
                if (await WaitingPreviosConvert(mutex) == false)
                {
                    return;
                }

                contoller = new ConvertProcessController(HandBrakeCLIFilePath);
                contoller.ConvertStateChangedEvent += new ConvertStateChangedHandler(ConvertStateChanged);

                for (currentFileIndex = 0; currentFileIndex < SourceFileList.Count; currentFileIndex++)
                {
                    string currentSourceFilePath = SourceFileList[currentFileIndex];
                    var    replaceParam          = CreateReplaceParam(ConvertSettingName, currentSourceFilePath, DestinationFolder);

                    // 変換開始時にステータス更新
                    OnConvertStateChanged((int)(((double)currentFileIndex / SourceFileList.Count) * 100), 0,
                                          $"{currentFileIndex}/{SourceFileList.Count}", "スキャン中");

                    // 変換元が存在しない場合はスキップ
                    if (File.Exists(currentSourceFilePath) == false)
                    {
                        LogWindow.LogMessage($"元ファイルが存在しないのでスキップします。 File={currentSourceFilePath}", LogWindow.MessageType.Warning);
                        continue;
                    }

                    // 変換先にすでにファイルが有る場合はスキップ
                    if (IsAlreadyExistCompleteFolder(replaceParam))
                    {
                        continue;
                    }

                    // 一個のファイルを変換する
                    LogWindow.LogMessage($"Handbrakeで変換処理を開始します。 File={currentSourceFilePath}", LogWindow.MessageType.Information);
                    await contoller.ExecuteConvert(ConvertSetting, replaceParam);

                    LogWindow.LogMessage($"Handbrakeで変換処理を終了しました。 Status={contoller.Status} File={currentSourceFilePath}", LogWindow.MessageType.Information);

                    if (contoller.Status == Constant.ConvertFileStatus.Completed)
                    {
                        // 正常完了した場合は完了フォルダに移動
                        MoveCompleteFolder(currentSourceFilePath);
                    }
                    else
                    {
                        // 正常に完了しなかった場合は途中のファイルを削除する
                        DeleteNotCompleteFile(replaceParam);
                    }

                    // キャンセルされていたら中断
                    if (IsCancellationRequested || IsCancellationNextRequested)
                    {
                        break;
                    }
                }
            }

            // イベントを発行
            if (!IsCancellationRequested && !IsCancellationNextRequested)
            {
                OnConvertStateChanged(100, 100, $"{SourceFileList.Count}/{SourceFileList.Count}", "完了");
            }

            contoller = null;
        }