コード例 #1
0
        // 开始监控一个门
        public void BeginMonitor(DoorItem door)
        {
            lock (_syncRoot)
            {
                // 检查以前这个门是否已经有监控消息
                var message = _messages.Find((m) =>
                {
                    if (m.Door == door)
                    {
                        return(true);
                    }
                    return(false);
                });

                if (message != null)
                {
                    App.CurrentApp.Speak("补做遗留提交");
                    WpfClientInfo.WriteInfoLog($"对门 {message.Door.Name} 补做一次 submit (1)");

                    _func_submit?.Invoke(message.Door, false);
                    message.StartTime      = DateTime.Now; // 重新开始
                    message.HeartbeatTicks = RfidManager.LockHeartbeat;
                }
                else
                {
                    message = new MonitorMessage
                    {
                        Door           = door,
                        StartTime      = DateTime.Now,
                        HeartbeatTicks = RfidManager.LockHeartbeat
                    };
                    _messages.Add(message);
                }
            }
        }
コード例 #2
0
        // 处理一次监控任务
        public void ProcessTimeout()
        {
            lock (_syncRoot)
            {
                List <MonitorMessage> delete_messages = new List <MonitorMessage>();
                foreach (var message in _messages)
                {
                    // if (DateTime.Now - message.StartTime > TimeoutLength)
                    if (RfidManager.LockHeartbeat - message.HeartbeatTicks >= 2)
                    {
                        App.CurrentApp.Speak("超时补做提交");
                        WpfClientInfo.WriteInfoLog($"超时情况下,对门 {message.Door.Name} 补做一次 submit");

                        _func_submit?.Invoke(message.Door, true);
                        delete_messages.Add(message);

                        message.Door.Waiting--;
                    }
                }

                foreach (var message in delete_messages)
                {
                    _messages.Remove(message);
                }
            }
        }
コード例 #3
0
ファイル: ShelfData_sync.cs プロジェクト: cty901/dp2
        // 把 Actions 追加保存到本地数据库
        // 当本函数执行完以后,ActionInfo 对象的 ID 有了值,和数据库记录的 ID 对应
        public static async Task SaveActionsToDatabaseAsync(List <ActionInfo> actions)
        {
            try
            {
                using (var releaser = await _databaseLimit.EnterAsync())
                {
                    using (var context = new RequestContext())
                    {
                        context.Database.EnsureCreated();

                        var requests = FromActions(actions);
                        foreach (var request in requests)
                        {
                            // 注:这样一个一个保存可以保持 ID 的严格从小到大。因为这些事项之间是有严格顺序关系的(借和还顺序不能颠倒)
                            await context.Requests.AddRangeAsync(request);

                            int nCount = await context.SaveChangesAsync();

                            // 2020/4/27
                            // 如果是还书动作,需要更新它之前的全部同 PII 的借书动作的 LinkID 字段
                            if (request.Action == "return" || request.Action == "inventory")
                            {
                                var borrowRequests = context.Requests.
                                                     Where(o => o.PII == request.PII && o.Action == "borrow" && o.LinkID == null)
                                                     .ToList();
                                foreach (var item in borrowRequests)
                                {
                                    item.LinkID = request.ID.ToString();
                                    context.Requests.Update(item);
                                    await context.SaveChangesAsync();
                                }
                            }
                        }

                        Debug.Assert(requests.Count == actions.Count, "");
                        // 刷新 ActionInfo 对象的 ID
                        for (int i = 0; i < requests.Count; i++)
                        {
                            actions[i].ID = requests[i].ID;
                        }

                        WpfClientInfo.WriteInfoLog($"Actions 保存到本地数据库成功。内容如下:\r\n{ActionInfo.ToString(actions)}");
                    }
                }
            }
            catch (Exception ex)
            {
                WpfClientInfo.WriteErrorLog($"SaveActionsToDatabase() 出现异常: {ExceptionUtil.GetDebugText(ex)}");
                throw ex;
            }
        }
コード例 #4
0
        // sync/commerror/normalerror/空
        // 同步成功/通讯出错/一般出错/从未同步过

        // 从外部存储中装载尚未同步的 Actions
        // 注意:这些 Actions 应该先按照 PII 排序分组以后,一组一组进行处理
        public static async Task <List <ActionInfo> > LoadRetryActionsFromDatabaseAsync()
        {
            using (var releaser = await _databaseLimit.EnterAsync())
            {
                using (var context = new RequestContext())
                {
                    context.Database.EnsureCreated();
                    var items = context.Requests.Where(o => o.State != "sync" && o.State != "dontsync")
                                .OrderBy(o => o.ID).ToList();
                    var actions = FromRequests(items);
                    WpfClientInfo.WriteInfoLog($"从本地数据库装载 Actions 成功。内容如下:\r\n{ActionInfo.ToString(actions)}");
                    return(actions);
                }
            }
        }
コード例 #5
0
        // 启动盘点后台任务
        public static void StartInventoryTask()
        {
            if (_inventoryTask != null)
            {
                return;
            }

            CancellationToken token = App.CancelToken;

            token.Register(() =>
            {
                _eventInventory.Set();
            });

            _inventoryTask = Task.Factory.StartNew(async() =>
            {
                WpfClientInfo.WriteInfoLog("盘点后台线程开始");
                try
                {
                    while (token.IsCancellationRequested == false)
                    {
                        // await Task.Delay(TimeSpan.FromSeconds(10));
                        _eventInventory.WaitOne(_inventoryIdleLength);

                        token.ThrowIfCancellationRequested();

                        //
                        await ProcessingAsync();
                    }
                    _inventoryTask = null;
                }
                catch (OperationCanceledException)
                {
                }
                catch (Exception ex)
                {
                    WpfClientInfo.WriteErrorLog($"盘点后台线程出现异常: {ExceptionUtil.GetDebugText(ex)}");
                    App.SetError("inventory_worker", $"盘点后台线程出现异常: {ex.Message}");
                }
                finally
                {
                    WpfClientInfo.WriteInfoLog("盘点后台线程结束");
                }
            },
                                                   token,
                                                   TaskCreationOptions.LongRunning,
                                                   TaskScheduler.Default);
        }
コード例 #6
0
ファイル: ShelfData_sync.cs プロジェクト: cty901/dp2
        // 启动同步任务。此任务长期在后台运行
        public static void StartSyncTask()
        {
            if (_syncTask != null)
            {
                return;
            }

            CancellationToken token = _cancel.Token;

            token.Register(() =>
            {
                _eventSync.Set();
            });

            // 启动重试专用线程
            _syncTask = Task.Factory.StartNew(async() =>
            {
                WpfClientInfo.WriteInfoLog("重试专用线程开始");
                try
                {
                    while (token.IsCancellationRequested == false)
                    {
                        // TODO: 无论是整体退出,还是需要激活,都需要能中断 Delay
                        // Task.Delay(TimeSpan.FromSeconds(10)).Wait(token);
                        _eventSync.WaitOne(_syncIdleLength);
                        token.ThrowIfCancellationRequested();

#if REMOVED
                        // 顺便检查和确保连接到消息服务器
                        App.CurrentApp.EnsureConnectMessageServer().Wait(token);
#endif

#if REMOVED
                        // 顺便关闭天线射频
                        if (_tagAdded)
                        {
                            _ = Task.Run(async() =>
                            {
                                try
                                {
                                    await SelectAntennaAsync();
                                }
                                catch
                                {
                                    // TODO: 写入错误日志
                                }
                            });
                            _tagAdded = false;
                        }
#endif

                        if (PauseSubmit)
                        {
                            continue;
                        }

                        // 2020/6/21
                        if (ShelfData.LibraryNetworkCondition != "OK")
                        {
                            continue;
                        }

                        // TODO: 从本地数据库中装载需要同步的那些 Actions
                        List <ActionInfo> actions = await LoadRetryActionsFromDatabaseAsync();
                        if (actions.Count == 0)
                        {
                            continue;
                        }

                        // RefreshRetryInfo() ???

                        // 一般来说,只要 SubmitWindow 开着,就要显示请求情况结果。
                        // 特殊地,如果 SubmitWindow 没有开着,但本次至少有一个成功的请求结果了,那就专门打开 SubmitWindow 显示信息

                        int succeedCount = 0; // 同步成功的事项数量
                        int newCount     = 0; // 首次进行同步的事项数量

                        // 排序和分组。按照分组提交给 dp2library 服务器
                        // TODO: 但进度显示不应该太细碎?应该按照总的进度来显示
                        var groups = GroupActions(actions);

                        // List<MessageItem> messages = new List<MessageItem>();

                        // 准备对话框
                        // SubmitWindow progress = PageMenu.PageShelf?.OpenProgressWindow();
                        SubmitWindow progress = PageMenu.PageShelf?.ProgressWindow;

                        int start = 0;  // 当前 group 开始的偏移
                        int total = actions.Count;
                        foreach (var group in groups)
                        {
                            int current_count = group.Count;    // 当前 group 包含的动作数量

                            var result = await SubmitCheckInOutAsync(
                                (min, max, value, text) =>
                            {
                                // 2020/4/2
                                // 修正三个值
                                if (max != -1)
                                {
                                    max = total;
                                }
                                //if (min != -1)
                                //    min += start;
                                if (value != -1)
                                {
                                    value += start;
                                }

                                if (progress != null)
                                {
                                    App.Invoke(new Action(() =>
                                    {
                                        if (min == -1 && max == -1 && value == -1 &&
                                            groups.IndexOf(group) == groups.Count - 1)  // 只有最后一次才隐藏进度条
                                        {
                                            progress.ProgressBar.Visibility = Visibility.Collapsed;
                                        }
                                        else
                                        {
                                            progress.ProgressBar.Visibility = Visibility.Visible;
                                        }

                                        if (text != null)
                                        {
                                            progress.TitleText = text;  // + " " + (progress.Tag as string);
                                        }
                                        if (min != -1)
                                        {
                                            progress.ProgressBar.Minimum = min;
                                        }
                                        if (max != -1)
                                        {
                                            progress.ProgressBar.Maximum = max;
                                        }
                                        if (value != -1)
                                        {
                                            progress.ProgressBar.Value = value;
                                        }
                                    }));
                                }
                            },
                                group,
                                "auto_stop");

                            // TODO: 把 group 中报错的信息写入本地数据库的对应事项中

                            /*
                             * // 把已经处理成功的 Action 对应在本地数据库中的事项的状态修改
                             * List<ActionInfo> processed = new List<ActionInfo>();
                             * if (result.RetryActions != null)
                             * {
                             *  foreach (var action in group)
                             *  {
                             *      if (result.RetryActions.IndexOf(action) == -1)
                             *      {
                             *          ChangeDatabaseActionState(action.ID, "sync");
                             *          processed.Add(action);
                             *      }
                             *  }
                             * }
                             */
                            if (result.ProcessedActions != null)
                            {
                                // result.ProcessedActions.ForEach(o => { if (o.SyncCount == 0) newCount++; });

                                foreach (var action in result.ProcessedActions)
                                {
                                    if (action.State == "sync")
                                    {
                                        succeedCount++;
                                    }
                                    if (action.SyncCount == 1)
                                    {
                                        newCount++;
                                    }
                                    // sync/commerror/normalerror/空
                                    // 同步成功/通讯出错/一般出错/从未同步过
                                    await ChangeDatabaseActionStateAsync(action.ID, action);
                                }

                                // TODO: 通知消息正文是否也告知一下同一个 PII 后面有多少个动作被跳过处理?
                                MessageNotifyOverflow(result.ProcessedActions);
                            }

                            if (progress != null && progress.IsVisible)
                            {
                                // 根据全部和已处理集合得到未处理(被跳过的)集合
                                var skipped = GetSkippedActions(group, result.ProcessedActions);
                                foreach (var action in skipped)
                                {
                                    action.State         = "_";
                                    action.SyncErrorCode = "skipped";
                                    // action.SyncErrorInfo = "暂时跳过同步";
                                }

                                List <ActionInfo> display = new List <ActionInfo>(result.ProcessedActions);
                                display.AddRange(skipped);
                                // Thread.Sleep(3000);
                                // 刷新显示
                                App.Invoke(new Action(() =>
                                {
                                    progress?.Refresh(display);
                                }));
                            }

                            /*
                             * if (result.MessageDocument != null)
                             *  messages.AddRange(result.MessageDocument.Items);
                             */
                            start += current_count;
                        }

                        // TODO: 更新每个事项的 RetryCount。如果超过 10 次,要把 State 更新为 fail

                        // 将 submit 情况写入日志备查
                        // WpfClientInfo.WriteInfoLog($"重试提交请求:\r\n{ActionInfo.ToString(actions)}\r\n返回结果:{result.ToString()}");



#if REMOVED
                        // 如果本轮有成功的请求,并且进度窗口没有打开,则补充打开进度窗口
                        if ((progress == null || progress.IsVisible == false) &&
                            succeedCount > 0)
                        {
                            progress = PageMenu.PageShelf?.OpenProgressWindow();
                        }

                        // 把执行结果显示到对话框内
                        // 全部事项都重试失败的时候不需要显示
                        if (progress != null && progress.IsVisible &&
                            (succeedCount > 0 || newCount > 0))
                        {
                            Application.Current.Dispatcher.Invoke(new Action(() =>
                            {
                                MessageDocument doc = new MessageDocument();
                                doc.AddRange(messages);
                                progress?.PushContent(doc);
                            }));

                            // 显示出来
                            Application.Current.Dispatcher.Invoke(new Action(() =>
                            {
                                progress?.ShowContent();
                            }));
                        }
#endif
                    }
                    _syncTask = null;
                }
                catch (OperationCanceledException)
                {
                }
                catch (Exception ex)
                {
                    WpfClientInfo.WriteErrorLog($"重试专用线程出现异常: {ExceptionUtil.GetDebugText(ex)}");
                    App.SetError("sync", $"重试专用线程出现异常: {ex.Message}");
                }
                finally
                {
                    WpfClientInfo.WriteInfoLog("重试专用线程结束");
                }
            },
                                              token,
                                              TaskCreationOptions.LongRunning,
                                              TaskScheduler.Default);
        }
コード例 #7
0
ファイル: ShelfData_monitor.cs プロジェクト: zgren/dp2
        // 启动一般监控任务
        public static void StartMonitorTask()
        {
            if (_monitorTask != null)
            {
                return;
            }

            PerdayTask.StartPerdayTask();

            CancellationToken token = _cancel.Token;

            // bool download_complete = false;

            token.Register(() =>
            {
                _eventMonitor.Set();
            });

            _monitorTask = Task.Factory.StartNew(async() =>
            {
                WpfClientInfo.WriteInfoLog("书柜监控专用线程开始");
                try
                {
                    while (token.IsCancellationRequested == false)
                    {
                        // await Task.Delay(TimeSpan.FromSeconds(10));
                        _eventMonitor.WaitOne(_monitorIdleLength);

                        token.ThrowIfCancellationRequested();

                        // ***
                        // 关闭天线射频
                        if (_tagAdded)
                        {
                            _ = Task.Run(async() =>
                            {
                                try
                                {
                                    await SelectAntennaAsync();
                                }
                                catch (Exception ex)
                                {
                                    WpfClientInfo.WriteErrorLog($"关闭天线射频 SelectAntennaAsync() 时出现异常: {ExceptionUtil.GetDebugText(ex)}");
                                }
                            });
                            _tagAdded = false;
                        }

                        if (DateTime.Now - _lastDetectTime > _detectPeriod)
                        {
                            DetectLibraryNetwork();

                            _lastDetectTime = DateTime.Now;
                        }

                        // 提醒关门
                        WarningCloseDoor();

                        // 下载或同步读者信息
                        string startDate = LoadStartDate();
                        if (/*download_complete == false || */
                            string.IsNullOrEmpty(startDate) &&
                            _replicatePatronError == 0)
                        {
                            // 如果 Config 中没有记载断点位置,说明以前从来没有首次同步过。需要进行一次首次同步
                            if (string.IsNullOrEmpty(startDate))
                            {
                                // SaveStartDate("");

                                var repl_result = await PatronReplication.DownloadAllPatronRecordAsync(
                                    (text) =>
                                {
                                    WpfClientInfo.WriteInfoLog(text);
                                    PageShelf.TrySetMessage(null, text);
                                },
                                    token);
                                if (repl_result.Value == -1)
                                {
                                    // TODO: 判断通讯出错的错误码。如果是通讯出错,则稍后需要重试下载
                                    _replicatePatronError++;
                                }
                                else
                                {
                                    SaveStartDate(repl_result.StartDate);
                                }

                                // 立刻允许接着做一次零星同步
                                ActivateMonitor();
                            }
                            // download_complete = true;
                        }
                        else
                        {
                            // 进行零星同步
                            if (DateTime.Now - _lastReplicateTime > _replicatePeriod)
                            {
                                // string startDate = LoadStartDate();

                                // testing
                                // startDate = "20200507:0-";

                                if (string.IsNullOrEmpty(startDate) == false)
                                {
                                    string endDate = DateTimeUtil.DateTimeToString8(DateTime.Now);

                                    // parameters:
                                    //      strLastDate   处理中断或者结束时返回最后处理过的日期
                                    //      last_index  处理或中断返回时最后处理过的位置。以后继续处理的时候可以从这个偏移开始
                                    // return:
                                    //      -1  出错
                                    //      0   中断
                                    //      1   完成
                                    ReplicationResult repl_result = await PatronReplication.DoReplication(
                                        startDate,
                                        endDate,
                                        LogType.OperLog,
                                        token);
                                    if (repl_result.Value == -1)
                                    {
                                        WpfClientInfo.WriteErrorLog($"同步出错: {repl_result.ErrorInfo}");
                                    }
                                    else if (repl_result.Value == 1)
                                    {
                                        string lastDate = repl_result.LastDate + ":" + repl_result.LastIndex + "-";    // 注意 - 符号不能少。少了意思就会变成每次只获取一条日志记录了
                                        SaveStartDate(lastDate);
                                    }

                                    _lastReplicateTime = DateTime.Now;
                                }
                            }
                        }
                    }
                    _monitorTask = null;
                }
                catch (OperationCanceledException)
                {
                }
                catch (Exception ex)
                {
                    WpfClientInfo.WriteErrorLog($"书柜监控专用线程出现异常: {ExceptionUtil.GetDebugText(ex)}");
                    App.SetError("shelf_monitor", $"书柜监控专用线程出现异常: {ex.Message}");
                }
                finally
                {
                    WpfClientInfo.WriteInfoLog("书柜监控专用线程结束");
                }
            },
                                                 token,
                                                 TaskCreationOptions.LongRunning,
                                                 TaskScheduler.Default);
        }
コード例 #8
0
        // 从 _entityList 中取出一批事项进行处理。由于是复制出来处理的,所以整个处理过程中(除了取出和最后删除的瞬间)不用对 _entityList 加锁
        // 对每一个事项,要进行如下处理:
        //  1) 获得册记录和书目摘要
        //  2) 尝试请求还书
        //  3) 请求设置 UID
        //  4) 修改 currentLocation 和 location
        static async Task ProcessingAsync()
        {
            var list = CopyList();

            foreach (var state in list)
            {
                // state.State = "???";
                try
                {
                    if (state.NewState == "open")
                    {
                        continue;
                    }

                    Debug.Assert(state.NewState == "close");

                    List <ActionInfo> actions = null;

                    try
                    {
                        DateTime start = DateTime.Now;

                        var result = await ShelfData.RefreshInventoryAsync(state.Door);

                        WpfClientInfo.WriteInfoLog($"针对门 {state.Door.Name} 执行 RefreshInventoryAsync() 耗时 {(DateTime.Now - start).TotalSeconds.ToString()}");

                        start = DateTime.Now;

                        // 2020/4/21 把这两句移动到 try 范围内
                        await SaveDoorActions(state.Door, true);

                        WpfClientInfo.WriteInfoLog($"针对门 {state.Door.Name} 执行 SaveDoorActions() 耗时 {(DateTime.Now - start).TotalSeconds.ToString()}");

                        start = DateTime.Now;

                        actions = ShelfData.PullActions();
                        WpfClientInfo.WriteInfoLog($"针对门 {state.Door.Name} 执行 PullActions() 耗时 {(DateTime.Now - start).TotalSeconds.ToString()}");
                    }
                    finally
                    {
                        state.Door.DecWaiting();
                        //WpfClientInfo.WriteInfoLog($"--decWaiting() door '{e.Door.Name}' state changed");
                    }


                    // 注: 调用完成后门控件上的 +- 数字才会消失
                    var task = PageMenu.PageShelf.DoRequestAsync(actions, "");

                    App.SetError("processing", null);
                }
                catch (Exception ex)
                {
                    WpfClientInfo.WriteErrorLog($"ProcessingAsync() 出现异常: {ExceptionUtil.GetDebugText(ex)}");
                    App.SetError("processing", $"ProcessingAsync() 出现异常: {ex.Message}");
                }
                finally
                {
                    // state.State = "";
                }
            }

            // 把处理过的 entity 从 list 中移走
            RemoveList(list);

            // 2020/11/21
            // 如果发现队列里面又有新的对象,则立即激活任务
            if (GetListCount() > 0)
            {
                ActivateTask();
            }
        }
コード例 #9
0
        // 启动一般监控任务
        public static void StartMonitorTask()
        {
            if (_monitorTask != null)
            {
                return;
            }

            CancellationToken token = App.CancelToken;

            token.Register(() =>
            {
                _eventMonitor.Set();
            });

            _monitorTask = Task.Factory.StartNew(async() =>
            {
                WpfClientInfo.WriteInfoLog("SIP 监控专用线程开始");
                try
                {
                    while (token.IsCancellationRequested == false)
                    {
                        // await Task.Delay(TimeSpan.FromSeconds(10));
                        _eventMonitor.WaitOne(_monitorIdleLength);

                        token.ThrowIfCancellationRequested();

                        if (DateTime.Now - _lastDetectTime > _detectPeriod)
                        {
                            var detect_result = await DetectSipNetworkAsync();
                            _lastDetectTime   = DateTime.Now;

                            // testing
                            //detect_result.Value = -1;
                            //detect_result.ErrorInfo = "测试文字";

                            if (detect_result.Value != 1)
                            {
                                App.OpenErrorWindow(detect_result.ErrorInfo);
                            }
                            else
                            {
                                App.CloseErrorWindow();
                            }
                        }
                    }
                    _monitorTask = null;
                }
                catch (OperationCanceledException)
                {
                }
                catch (Exception ex)
                {
                    WpfClientInfo.WriteErrorLog($"SIP 监控专用线程出现异常: {ExceptionUtil.GetDebugText(ex)}");
                    App.SetError("monitor", $"SIP 监控专用线程出现异常: {ex.Message}");
                }
                finally
                {
                    WpfClientInfo.WriteInfoLog("SIP 监控专用线程结束");
                }
            },
                                                 token,
                                                 TaskCreationOptions.LongRunning,
                                                 TaskScheduler.Default);
        }
コード例 #10
0
ファイル: ShelfData_monitor.cs プロジェクト: kevinlau2015/dp2
        // 启动一般监控任务
        public static void StartMonitorTask()
        {
            if (_monitorTask != null)
            {
                return;
            }

            CancellationToken token = _cancel.Token;
            bool download_complete  = false;

            token.Register(() =>
            {
                _eventMonitor.Set();
            });

            _monitorTask = Task.Factory.StartNew(async() =>
            {
                WpfClientInfo.WriteInfoLog("监控专用线程开始");
                try
                {
                    while (token.IsCancellationRequested == false)
                    {
                        // await Task.Delay(TimeSpan.FromSeconds(10));
                        _eventMonitor.WaitOne(_monitorIdleLength);

                        token.ThrowIfCancellationRequested();

                        // ***
                        // 关闭天线射频
                        if (_tagAdded)
                        {
                            _ = Task.Run(async() =>
                            {
                                try
                                {
                                    await SelectAntennaAsync();
                                }
                                catch (Exception ex)
                                {
                                    WpfClientInfo.WriteErrorLog($"关闭天线射频 SelectAntennaAsync() 时出现异常: {ExceptionUtil.GetDebugText(ex)}");
                                }
                            });
                            _tagAdded = false;
                        }

                        if (DateTime.Now - _lastDetectTime > _detectPeriod)
                        {
                            DetectLibraryNetwork();

                            _lastDetectTime = DateTime.Now;
                        }

                        // 提醒关门
                        WarningCloseDoor();

                        // 下载或同步读者信息
                        string startDate = LoadStartDate();
                        if (/*download_complete == false || */
                            string.IsNullOrEmpty(startDate))
                        {
                            // 如果 Config 中没有记载断点位置,说明以前从来没有首次同步过。需要进行一次首次同步
                            if (string.IsNullOrEmpty(startDate))
                            {
                                // SaveStartDate("");

                                var repl_result = await PatronReplication.DownloadAllPatronRecordAsync(token);
                                if (repl_result.Value == -1)
                                {
                                    // TODO: 判断通讯出错的错误码。如果是通讯出错,则稍后需要重试下载
                                }
                                else
                                {
                                    SaveStartDate(repl_result.StartDate);
                                }

                                // 立刻允许接着做一次零星同步
                                ActivateMonitor();
                            }
                            // download_complete = true;
                        }
                        else
                        {
                            // 进行零星同步
                            if (DateTime.Now - _lastReplicateTime > _replicatePeriod)
                            {
                                // string startDate = LoadStartDate();

                                // testing
                                // startDate = "20200507:0-";

                                if (string.IsNullOrEmpty(startDate) == false)
                                {
                                    string endDate = DateTimeUtil.DateTimeToString8(DateTime.Now);

                                    // parameters:
                                    //      strLastDate   处理中断或者结束时返回最后处理过的日期
                                    //      last_index  处理或中断返回时最后处理过的位置。以后继续处理的时候可以从这个偏移开始
                                    // return:
                                    //      -1  出错
                                    //      0   中断
                                    //      1   完成
                                    ReplicationResult repl_result = PatronReplication.DoReplication(
                                        startDate,
                                        endDate,
                                        LogType.OperLog,
                                        token);
                                    if (repl_result.Value == -1)
                                    {
                                        WpfClientInfo.WriteErrorLog($"同步出错: {repl_result.ErrorInfo}");
                                    }
                                    else if (repl_result.Value == 1)
                                    {
                                        string lastDate = repl_result.LastDate + ":" + repl_result.LastIndex + "-";    // 注意 - 符号不能少。少了意思就会变成每次只获取一条日志记录了
                                        SaveStartDate(lastDate);
                                    }

                                    _lastReplicateTime = DateTime.Now;
                                }
                            }
                        }

                        // 检查升级 dp2ssl
                        if (_updated == false
                            // && StringUtil.IsDevelopMode() == false
                            && ApplicationDeployment.IsNetworkDeployed == false &&
                            DateTime.Now - _lastUpdateTime > _updatePeriod)
                        {
                            WpfClientInfo.WriteInfoLog("开始自动检查升级");
                            // result.Value:
                            //      -1  出错
                            //      0   经过检查发现没有必要升级
                            //      1   成功
                            //      2   成功,但需要立即重新启动计算机才能让复制的文件生效
                            var update_result = await GreenInstaller.InstallFromWeb("http://dp2003.com/dp2ssl/v1_dev",
                                                                                    "c:\\dp2ssl",
                                                                                    "delayExtract,updateGreenSetupExe",
                                                                                    //true,
                                                                                    //true,
                                                                                    token,
                                                                                    null);
                            if (update_result.Value == -1)
                            {
                                WpfClientInfo.WriteErrorLog($"自动检查升级出错: {update_result.ErrorInfo}");
                            }
                            else
                            {
                                WpfClientInfo.WriteInfoLog($"结束自动检查升级 update_result:{update_result.ToString()}");
                            }

                            if (update_result.Value == 1 || update_result.Value == 2)
                            {
                                App.TriggerUpdated("重启可使用新版本");
                                _updated = true;
                                PageShelf.TrySetMessage(null, "dp2SSL 升级文件已经下载成功,下次重启时可自动升级到新版本");
                            }
                            _lastUpdateTime = DateTime.Now;
                        }
                    }
                    _monitorTask = null;
                }
                catch (OperationCanceledException)
                {
                }
                catch (Exception ex)
                {
                    WpfClientInfo.WriteErrorLog($"监控专用线程出现异常: {ExceptionUtil.GetDebugText(ex)}");
                    App.SetError("monitor", $"监控专用线程出现异常: {ex.Message}");
                }
                finally
                {
                    WpfClientInfo.WriteInfoLog("监控专用线程结束");
                }
            },
                                                 token,
                                                 TaskCreationOptions.LongRunning,
                                                 TaskScheduler.Default);
        }
コード例 #11
0
ファイル: SipChannel.cs プロジェクト: zgren/dp2
 public static void WriteInfoLog(string text)
 {
     WpfClientInfo.WriteInfoLog(text);
 }
コード例 #12
0
ファイル: InventoryData.cs プロジェクト: cty901/dp2
        // parameters:
        //      uid_table   返回 UID --> PII 对照表
        public static NormalResult DownloadUidTable(
            List <string> item_dbnames,
            Hashtable uid_table,
            delegate_showText func_showProgress,
            // Delegate_writeLog writeLog,
            CancellationToken token)
        {
            WpfClientInfo.WriteInfoLog($"开始下载全部册记录到本地缓存");
            LibraryChannel channel     = App.CurrentApp.GetChannel();
            var            old_timeout = channel.Timeout;

            channel.Timeout = TimeSpan.FromMinutes(5);  // 设置 5 分钟。因为册记录检索需要一定时间
            try
            {
                if (item_dbnames == null)
                {
                    long lRet = channel.GetSystemParameter(
                        null,
                        "item",
                        "dbnames",
                        out string strValue,
                        out string strError);
                    if (lRet == -1)
                    {
                        return new NormalResult
                               {
                                   Value     = -1,
                                   ErrorInfo = strError,
                                   ErrorCode = channel.ErrorCode.ToString()
                               }
                    }
                    ;
                    item_dbnames = StringUtil.SplitList(strValue);
                    StringUtil.RemoveBlank(ref item_dbnames);
                }

                foreach (string dbName in item_dbnames)
                {
                    func_showProgress?.Invoke($"正在从 {dbName} 获取信息 ...");

                    int nRedoCount = 0;
REDO:
                    if (token.IsCancellationRequested)
                    {
                        return new NormalResult
                               {
                                   Value     = -1,
                                   ErrorInfo = "用户中断"
                               }
                    }
                    ;
                    // 检索全部读者库记录
                    long lRet = channel.SearchItem(null,
                                                   dbName, // "<all>",
                                                   "",
                                                   -1,
                                                   "__id",
                                                   "left",
                                                   "zh",
                                                   null, // strResultSetName
                                                   "",   // strSearchStyle
                                                   "",   // strOutputStyle
                                                   out string strError);
                    if (lRet == -1)
                    {
                        WpfClientInfo.WriteErrorLog($"SearchItem() 出错, strError={strError}, channel.ErrorCode={channel.ErrorCode}");

                        // 一次重试机会
                        if (lRet == -1 &&
                            (channel.ErrorCode == ErrorCode.RequestCanceled || channel.ErrorCode == ErrorCode.RequestError) &&
                            nRedoCount < 2)
                        {
                            nRedoCount++;
                            goto REDO;
                        }

                        return(new NormalResult
                        {
                            Value = -1,
                            ErrorInfo = strError,
                            ErrorCode = channel.ErrorCode.ToString()
                        });
                    }

                    long hitcount = lRet;

                    WpfClientInfo.WriteInfoLog($"{dbName} 共检索命中册记录 {hitcount} 条");

                    // 把超时时间改短一点
                    channel.Timeout = TimeSpan.FromSeconds(20);

                    DateTime search_time = DateTime.Now;

                    int skip_count  = 0;
                    int error_count = 0;

                    if (hitcount > 0)
                    {
                        string strStyle = "id,cols,format:@coldef:*/barcode|*/location|*/uid";

                        // 获取和存储记录
                        ResultSetLoader loader = new ResultSetLoader(channel,
                                                                     null,
                                                                     null,
                                                                     strStyle, // $"id,xml,timestamp",
                                                                     "zh");

                        // loader.Prompt += this.Loader_Prompt;
                        int i = 0;
                        foreach (DigitalPlatform.LibraryClient.localhost.Record record in loader)
                        {
                            if (token.IsCancellationRequested)
                            {
                                return new NormalResult
                                       {
                                           Value     = -1,
                                           ErrorInfo = "用户中断"
                                       }
                            }
                            ;

                            if (record.Cols != null)
                            {
                                string barcode = "";

                                if (record.Cols.Length > 0)
                                {
                                    barcode = record.Cols[0];
                                }
                                string location = "";
                                if (record.Cols.Length > 1)
                                {
                                    location = record.Cols[1];
                                }
                                string uid = "";
                                if (record.Cols.Length > 2)
                                {
                                    uid = record.Cols[2];
                                }
                                if (string.IsNullOrEmpty(barcode) == false &&
                                    string.IsNullOrEmpty(uid) == false)
                                {
                                    uid_table[uid] = barcode;
                                }
                            }

                            i++;
                        }
                    }

                    WpfClientInfo.WriteInfoLog($"dbName='{dbName}'。skip_count={skip_count}, error_count={error_count}");
                }
                return(new NormalResult
                {
                    Value = uid_table.Count,
                });
            }
            catch (Exception ex)
            {
                WpfClientInfo.WriteErrorLog($"DownloadItemRecordAsync() 出现异常:{ExceptionUtil.GetDebugText(ex)}");

                return(new NormalResult
                {
                    Value = -1,
                    ErrorInfo = $"DownloadItemRecordAsync() 出现异常:{ex.Message}"
                });
            }
            finally
            {
                channel.Timeout = old_timeout;
                App.CurrentApp.ReturnChannel(channel);

                WpfClientInfo.WriteInfoLog($"结束下载全部读者记录到本地缓存");
            }
        }