public async Task UpdatePlaylogAsync()
        {
            await LoadGlobalMusicDataTable();

            DebugLogger.WriteLine("PlaylogDetailRecord更新の開始");
            List <TableUnit> savedPlaylogDetailRecordUnits = null;

            {
                var   readAsync = ReadPlaylogDetailRecordAsync("./test.csv");
                await readAsync;
                savedPlaylogDetailRecordUnits = readAsync.Result;
            }

            DebugLogger.WriteLine("Playlog の取得");
            IPlaylogRecordTable <IPlaylogRecordTableUnit> playlogRecord = null;
            {
                var   playlogSend = chunithmNetConnector.GetPlaylogAsync();
                await playlogSend;

                if (!playlogSend.Result.Success)
                {
                    throw new Exception("Playlogの取得に失敗しました");
                }

                var _playlogRecord = new PlaylogRecordTable();
                _playlogRecord.Add(playlogSend.Result.Playlog);
                playlogRecord = _playlogRecord;
            }

            List <TableUnit> updatedPlaylogDetailRecordUnits = null;

            {
                var   getAsync = GetUpdatedPlaylogDetailRecordUnitsAsync(playlogRecord, savedPlaylogDetailRecordUnits.LastOrDefault());
                await getAsync;
                updatedPlaylogDetailRecordUnits = getAsync.Result;
            }

            if (updatedPlaylogDetailRecordUnits.Count == 0)
            {
                DebugLogger.WriteLine("更新データなし");
                return;
            }

            DebugLogger.WriteLine("楽曲別レコードテーブル生成");
            var playlogDetailRecordUnitsGroupByMusic = GroupByMusic(updatedPlaylogDetailRecordUnits);

            DebugLogger.WriteLine("楽曲別レコードテーブル書き込み");
            await WritePlaylogDetailRecordByMusic(updatedPlaylogDetailRecordUnits);

            DebugLogger.WriteLine("更新データ書き込み");
            {
                var record = new Table();

                foreach (var recordUnit in savedPlaylogDetailRecordUnits)
                {
                    record.RecordUnits.Add(recordUnit);
                }

                foreach (var recordUnit in updatedPlaylogDetailRecordUnits)
                {
                    record.RecordUnits.Add(recordUnit);
                }

                var writer = new TableCsvWriter();
                writer.Set(record);
                writer.Write("./test.csv");
            }

            DebugLogger.WriteLine("Done.");
        }
        private async Task WritePlaylogDetailRecordByMusic(List <TableUnit> playlogDetailRecordUnits)
        {
            var musicDetails            = new Dictionary <string, MusicDetail>();
            var writer                  = new TableCsvWriter();
            var recordUnitsGroupByMusic = GroupByMusic(playlogDetailRecordUnits);

            foreach (var musicInfo in recordUnitsGroupByMusic.Keys)
            {
                var directory = GetDirectoryPath(musicInfo.Item1, musicInfo.Item2);
                if (!Directory.Exists(directory))
                {
                    Directory.CreateDirectory(directory);
                }

                var currentIndex = 1;
                if (ExistsPlaylogDetailRecordFile(directory, musicInfo, currentIndex))
                {
                    DebugLogger.WriteLine($"{musicInfo.Item1}({musicInfo.Item2})の既存データ読み込み");
                    while (ExistsPlaylogDetailRecordFile(directory, musicInfo, currentIndex + 1))
                    {
                        currentIndex++;
                    }

                    var   readAsync = ReadPlaylogDetailRecordAsync(GetPlaylogDetailRecordFilePath(directory, musicInfo, currentIndex));
                    await readAsync;
                    var   savedPlaylogDetailRecordUnits = readAsync.Result;

                    var lastPlayDate = savedPlaylogDetailRecordUnits.LastOrDefault()?.PlaylogDetail.PlayDate ?? new DateTime();
                    var startNumber  = savedPlaylogDetailRecordUnits.LastOrDefault()?.Number + 1 ?? 1;
                    if (recordUnitsGroupByMusic[musicInfo].Any(u => u.PlaylogDetail.PlayDate > lastPlayDate))
                    {
                        var updatedPlaylogDetailRecordUnits = new List <TableUnit>();
                        if (musicInfo.Item2 != Difficulty.WorldsEnd)
                        {
                            var   getAsync = GetMusicDetail(musicDetails, musicInfo.Item1);
                            await getAsync;
                            var   musicDetailUnit   = getAsync.Result.GetUnit(musicInfo.Item2);
                            var   sourceRecordUnits = recordUnitsGroupByMusic[musicInfo].Where(u => u.PlaylogDetail.PlayDate > lastPlayDate).ToList();
                            var   startPlayCount    = musicDetailUnit.PlayCount - sourceRecordUnits.Count + 1;
                            for (var i = 0; i < sourceRecordUnits.Count; i++)
                            {
                                var cloneRecordUnit = sourceRecordUnits[i].Clone();
                                cloneRecordUnit.Number     = startNumber + i;
                                cloneRecordUnit.PlayCount  = startPlayCount + i;
                                cloneRecordUnit.LinkNumber = sourceRecordUnits[i].Number;

                                sourceRecordUnits[i].LinkNumber = cloneRecordUnit.Number;

                                updatedPlaylogDetailRecordUnits.Add(cloneRecordUnit);
                            }
                        }
                        else
                        {
                            var sourceRecordUnits = recordUnitsGroupByMusic[musicInfo].Where(u => u.PlaylogDetail.PlayDate > lastPlayDate).ToList();
                            for (var i = 0; i < sourceRecordUnits.Count; i++)
                            {
                                var cloneRecordUnit = sourceRecordUnits[i].Clone();
                                cloneRecordUnit.Number     = startNumber + i;
                                cloneRecordUnit.Number     = startNumber + i;
                                cloneRecordUnit.LinkNumber = sourceRecordUnits[i].Number;

                                sourceRecordUnits[i].LinkNumber = cloneRecordUnit.Number;

                                updatedPlaylogDetailRecordUnits.Add(cloneRecordUnit);
                            }
                        }

                        var playlogDetailRecord = new Table();

                        foreach (var recordUnit in savedPlaylogDetailRecordUnits)
                        {
                            playlogDetailRecord.RecordUnits.Add(recordUnit);
                        }

                        foreach (var recordUnit in updatedPlaylogDetailRecordUnits)
                        {
                            playlogDetailRecord.RecordUnits.Add(recordUnit);
                        }

                        DebugLogger.WriteLine($"{musicInfo.Item1}({musicInfo.Item2})の書き出し");
                        writer.Set(playlogDetailRecord);
                        writer.Write(GetPlaylogDetailRecordFilePath(directory, musicInfo, currentIndex));
                    }
                }
                else
                {
                    var updatedPlaylogDetailRecordUnits = new List <TableUnit>();
                    var startNumber = 1;
                    if (musicInfo.Item2 != Difficulty.WorldsEnd)
                    {
                        var   getAsync = GetMusicDetail(musicDetails, musicInfo.Item1);
                        await getAsync;
                        var   musicDetailUnit   = getAsync.Result.GetUnit(musicInfo.Item2);
                        var   sourceRecordUnits = recordUnitsGroupByMusic[musicInfo];
                        var   startPlayCount    = (musicDetailUnit?.PlayCount - sourceRecordUnits.Count + 1) ?? 0;
                        for (var i = 0; i < sourceRecordUnits.Count; i++)
                        {
                            var cloneRecordUnit = sourceRecordUnits[i].Clone();
                            cloneRecordUnit.Number     = startNumber + i;
                            cloneRecordUnit.PlayCount  = startPlayCount + i;
                            cloneRecordUnit.LinkNumber = sourceRecordUnits[i].Number;

                            sourceRecordUnits[i].LinkNumber = cloneRecordUnit.Number;

                            updatedPlaylogDetailRecordUnits.Add(cloneRecordUnit);
                        }
                    }
                    else
                    {
                        var sourceRecordUnits = recordUnitsGroupByMusic[musicInfo];
                        for (var i = 0; i < sourceRecordUnits.Count; i++)
                        {
                            var cloneRecordUnit = sourceRecordUnits[i].Clone();
                            cloneRecordUnit.Number     = startNumber + i;
                            cloneRecordUnit.PlayCount  = startNumber + i;
                            cloneRecordUnit.LinkNumber = sourceRecordUnits[i].Number;

                            sourceRecordUnits[i].LinkNumber = cloneRecordUnit.Number;

                            updatedPlaylogDetailRecordUnits.Add(cloneRecordUnit);
                        }
                    }

                    var playlogDetailRecord = new Table();

                    foreach (var recordUnit in updatedPlaylogDetailRecordUnits)
                    {
                        playlogDetailRecord.RecordUnits.Add(recordUnit);
                    }

                    DebugLogger.WriteLine($"{musicInfo.Item1}({musicInfo.Item2})の書き出し");
                    writer.Set(playlogDetailRecord);
                    writer.Write(GetPlaylogDetailRecordFilePath(directory, musicInfo, currentIndex));
                }
            }
        }