Example #1
0
        // ====================================================================
        // protected 関数
        // ====================================================================

        // --------------------------------------------------------------------
        // ネビュラコア(同期)のメインルーチン
        // --------------------------------------------------------------------
        protected override async Task CoreMainAsync()
        {
#if DEBUGz
            Debug.WriteLine("priority before: " + Thread.CurrentThread.Priority.ToString());
            Thread.CurrentThread.Priority = ThreadPriority.Lowest;
            Debug.WriteLine("priority after: " + Thread.CurrentThread.Priority.ToString());
#endif
            YlCommon.SetLogWriterSyncDetail(_logWriterSyncDetail);

            while (true)
            {
                MainEvent.WaitOne();
                Debug.Assert(MainWindowViewModel != null, "Syclin.CoreMain() MainWindowViewModel is null");
                Int32 startTick = Environment.TickCount;

                try
                {
                    YlModel.Instance.EnvModel.AppCancellationTokenSource.Token.ThrowIfCancellationRequested();
                    if (YlModel.Instance.EnvModel.YukaListerWholeStatus == YukaListerStatus.Error)
                    {
                        continue;
                    }
                    if (!YlModel.Instance.EnvModel.YlSettings.SyncMusicInfoDb)
                    {
                        continue;
                    }

                    IsActive = true;
                    YlModel.Instance.EnvModel.LogWriter.LogMessage(Common.TRACE_EVENT_TYPE_STATUS, GetType().Name + " アクティブ化。");

                    // ログイン
                    MainWindowViewModel.SetStatusBarMessageWithInvoke(Common.TRACE_EVENT_TYPE_STATUS, "同期準備中...");
                    await LoginToSyncServerAsync();

                    // データベースをバックアップ
                    using MusicInfoContextDefault musicInfoContextDefault = new();
                    musicInfoContextDefault.BackupDatabase();
                    using YukariStatisticsContext yukariStatisticsContext = new();
                    yukariStatisticsContext.BackupDatabase();

                    // 再取得の場合は楽曲情報データベース初期化
                    CreateDatabaseIfNeeded(musicInfoContextDefault, yukariStatisticsContext);

                    // ダウンロード
                    (Int32 numTotalDownloads, Int32 numTotalImports) = await DownloadSyncDataAsync();

                    // アップロード
                    Int32 numTotalUploads = await UploadSyncDataAsync();

                    if (numTotalUploads > 0)
                    {
                        // アップロードを行った場合は、自身がアップロードしたデータの更新日・Dirty を更新するために再ダウンロードが必要
                        (numTotalDownloads, numTotalImports) = await DownloadSyncDataAsync();
                    }

                    // 完了表示
                    MainWindowViewModel.SetStatusBarMessageWithInvoke(Common.TRACE_EVENT_TYPE_STATUS, "データベース同期完了(ダウンロード"
                                                                      + (numTotalDownloads == 0 ? "無" : " " + numTotalDownloads.ToString("#,0") + " 件、うち " + numTotalImports.ToString("#,0") + " 件インポート")
                                                                      + "、アップロード" + (numTotalUploads == 0 ? "無" : " " + numTotalUploads.ToString("#,0") + " 件") + ")");

                    // 起動直後は Syclin と Yurelin が両方起動され、Syclin による属性未確認データのアップロード&ダウンロードと、Yurelin による属性確認が競合し、属性未確認の状態に戻ることがある
                    // Syclin スリープ化直前に Yurelin を起動し、再度属性確認が行われるようにする
                    YlCommon.ActivateYurelinIfNeeded();
                }
                catch (OperationCanceledException)
                {
                    return;
                }
                catch (Exception excep)
                {
                    DbCommon.LogDatabaseExceptionIfCan(excep);

                    // メッセージボックスではなくステータスバーにエラー表示
                    MainWindowViewModel.SetStatusBarMessageWithInvoke(TraceEventType.Error, excep.Message);
                    YlModel.Instance.EnvModel.LogWriter.LogMessage(Common.TRACE_EVENT_TYPE_STATUS, " スタックトレース:\n" + excep.StackTrace);
                }

                IsActive = false;
                TimeSpan timeSpan = new(YlCommon.MiliToHNano(Environment.TickCount - startTick));
                YlModel.Instance.EnvModel.LogWriter.LogMessage(Common.TRACE_EVENT_TYPE_STATUS, GetType().Name + " スリープ化:アクティブ時間:" + timeSpan.ToString(@"hh\:mm\:ss"));
            }
        }
Example #2
0
        // ====================================================================
        // protected 関数
        // ====================================================================

        // --------------------------------------------------------------------
        // ネビュラコア(検索データ作成)のメインルーチン
        // --------------------------------------------------------------------
        protected override Task CoreMainAsync()
        {
            while (true)
            {
                MainEvent.WaitOne();
                Int32 startTick = Environment.TickCount;

                try
                {
                    YlModel.Instance.EnvModel.AppCancellationTokenSource.Token.ThrowIfCancellationRequested();
                    if (YlModel.Instance.ProjModel.UndoneTargetFolderInfo() == null)
                    {
                        continue;
                    }

                    YlModel.Instance.EnvModel.YukaListerPartsStatus[(Int32)YukaListerPartsStatusIndex.Sifolin] = YukaListerStatus.Running;
                    YlModel.Instance.EnvModel.LogWriter.LogMessage(Common.TRACE_EVENT_TYPE_STATUS, GetType().Name + " アクティブ化。");
                    if (YlModel.Instance.EnvModel.YlSettings.ApplyMusicInfoIntelligently)
                    {
                        YlModel.Instance.EnvModel.LogWriter.LogMessage(Common.TRACE_EVENT_TYPE_STATUS, "楽曲情報データベースが不十分な場合の誤適用を軽減する設定。");
                    }

                    MusicInfoDatabaseToMemory();

                    _prevFolderTaskDetail = FolderTaskDetail.Done;
                    while (true)
                    {
                        TargetFolderInfo?targetFolderInfo;

                        // 削除
                        targetFolderInfo = YlModel.Instance.ProjModel.FindTargetFolderInfo(FolderTaskDetail.Remove);
                        if (targetFolderInfo != null)
                        {
                            Remove(targetFolderInfo);
                            continue;
                        }

                        // キャッシュ活用(全体の動作状況がエラーではない場合のみ)
                        if (YlModel.Instance.EnvModel.YukaListerWholeStatus != YukaListerStatus.Error)
                        {
                            targetFolderInfo = YlModel.Instance.ProjModel.FindTargetFolderInfo(FolderTaskDetail.CacheToDisk);
                            if (targetFolderInfo != null)
                            {
                                CacheToDisk(targetFolderInfo);
                                continue;
                            }
                        }

                        // すべてのフォルダーのキャッシュ活用が終わったら Yurelin をアクティブ化する
                        // 起動直後に前回のゆかり予約を解析することを想定している
                        if (_prevFolderTaskDetail == FolderTaskDetail.CacheToDisk)
                        {
                            Debug.WriteLine("Sifolin.CoreMain() キャッシュ活用後の Yurelin アクティブ化");
                            YlCommon.ActivateYurelinIfNeeded();
                        }

                        // 更新削除
                        targetFolderInfo = YlModel.Instance.ProjModel.FindTargetFolderInfo(FolderTaskDetail.UpdateRemove);
                        if (targetFolderInfo != null)
                        {
                            UpdateRemove(targetFolderInfo);
                            continue;
                        }

                        // 更新サブフォルダー検索
                        targetFolderInfo = YlModel.Instance.ProjModel.FindTargetFolderInfo(FolderTaskDetail.UpdateFindSubFolders);
                        if (targetFolderInfo != null)
                        {
                            UpdateFindSubFolders(targetFolderInfo);
                            continue;
                        }

                        // サブフォルダー検索
                        targetFolderInfo = YlModel.Instance.ProjModel.FindTargetFolderInfo(FolderTaskDetail.FindSubFolders);
                        if (targetFolderInfo != null)
                        {
                            FindSubFolders(targetFolderInfo);
                            continue;
                        }

                        // ファイル名追加
                        targetFolderInfo = YlModel.Instance.ProjModel.FindTargetFolderInfo(FolderTaskDetail.AddFileNames);
                        if (targetFolderInfo != null)
                        {
                            AddFileNames(targetFolderInfo);
                            continue;
                        }

                        // ファイル情報追加
                        targetFolderInfo = YlModel.Instance.ProjModel.FindTargetFolderInfo(FolderTaskDetail.AddInfos);
                        if (targetFolderInfo != null)
                        {
                            AddInfos(targetFolderInfo);
                            continue;
                        }

                        // メモリー DB → ディスク DB(全体の動作状況がエラーではない場合のみ)
                        if (_needsMemoryDbToDiskDb && YlModel.Instance.EnvModel.YukaListerWholeStatus != YukaListerStatus.Error)
                        {
                            MemoryToDisk();
                            _needsMemoryDbToDiskDb = false;
                            continue;
                        }

                        // メモリー DB → キャッシュ DB
                        if (_needsMemoryDbToCacheDb)
                        {
                            MemoryToCache();
                            _needsMemoryDbToCacheDb = false;
                            continue;
                        }

                        // Kamlin アクティブ化
                        YlCommon.ActivateKamlinIfNeeded();

                        // Yurelin アクティブ化
                        YlCommon.ActivateYurelinIfNeeded();

                        // やることが無くなったのでループを抜けて待機へ向かう
                        break;
                    }
                }
                catch (OperationCanceledException)
                {
                    return(Task.CompletedTask);
                }
                catch (Exception ex)
                {
                    YlModel.Instance.EnvModel.NebulaCoreErrors.Enqueue(GetType().Name + " ループ稼働時エラー:\n" + ex.Message);
                    YlModel.Instance.EnvModel.LogWriter.LogMessage(Common.TRACE_EVENT_TYPE_STATUS, " スタックトレース:\n" + ex.StackTrace);
                }

                // 念のため最後に表示を更新
                YlModel.Instance.EnvModel.YukaListerPartsStatus[(Int32)YukaListerPartsStatusIndex.Sifolin] = YukaListerStatus.Ready;
                YlModel.Instance.EnvModel.IsMainWindowDataGridCountChanged = true;

                TimeSpan timeSpan = new(YlCommon.MiliToHNano(Environment.TickCount - startTick));
                YlModel.Instance.EnvModel.LogWriter.LogMessage(Common.TRACE_EVENT_TYPE_STATUS, GetType().Name + " スリープ化:アクティブ時間:" + timeSpan.ToString(@"hh\:mm\:ss"));
            }
        }