private void initializeActions() { #region Items(Blocks/NPTs) actions //----------------------- ADD BLOCK ------------------------------- _actionLoadItem = (object data) => { try { var actionData = data as PPRange; if (!actionData.IsValidRange()) return; #region Load blockInfos var blockInfos = new DataServices.BlockDataService() .GetInRange(actionData.Start, actionData.End).ToArray(); //add each blockInfo to cache foreach (var blockInfo in blockInfos) { //find b in cache PPItemBlock b; lock (_cacheLock) b = _blocks[blockInfo.StationIndex].FirstOrDefault(x => x.Id == blockInfo.Id); if (b == null) { //new block (not in cache) is found //create the PPItemBlock and load full data //set HasVm to false b = new PPItemBlock(blockInfo.Id); lock (_cacheLock) { //add to cache _blocks[blockInfo.StationIndex].Add(b); } } else { //newer version (of an existing block in cache) is found lock (_cacheLock) { if (b.Model.ModifiedDate != blockInfo.ModifiedDate) { //reload b //set HasVm to false b.Reload(); } } } if (!_force && !_qThreadAlive) return; Thread.Sleep(10); } #endregion #region Load NptInfos //find npt Ids within the range var nptInfos = new DataServices.NPTDataService() .GetInRange(actionData.Start, actionData.End).ToArray(); //add each nptInfo to cache foreach (var nptInfo in nptInfos) { //find n in cache PPItemNpt n; lock (_cacheLock) n = _npts[nptInfo.StationIndex].FirstOrDefault(x => x.Id == nptInfo.Id); if (n == null) { //new npt (not in cache) is found //create the PPItemNPT and load full data //set HasVm to false n = new PPItemNpt(nptInfo.Id); lock (_cacheLock) { //add to cache _npts[nptInfo.StationIndex].Add(n); } } else { //newer version (of an existing block in cache) is found //check for newer version??? } if (!_force && !_qThreadAlive) return; Thread.Sleep(5); } #endregion #region find VIndex of each item in cache for (int st = 0; st < _stations; st++) { lock (_cacheLock) { if (_blocks[st].Any() || _npts[st].Any()) { //find VIndexes for station[st] (row) var row = (_blocks[st].Concat<PPItemBase>(_npts[st])) .OrderBy(x => x.Start) .ToArray(); int maxV = 1; for (int i = 0; i < row.Length; i++) { //block (b) var item = row[i]; //find VIndex of block (b) if (i == 0) { item.VIndex = 0; } else { //search through previous blocks var targetRow = row .Take(i) .GroupBy(g => g.VIndex) .FirstOrDefault(g => g .All(x => (x.End - item.Start < TimeSpan.FromSeconds(1)))); if (targetRow == null) { //non of rows has space item.VIndex = maxV; maxV++; } else { //nom is the row item.VIndex = targetRow.First().VIndex; } } //fire event to add it if (!PPItemBase.IsNull(item)) { if (item is PPItemBlock) _dispatcher.Invoke(() => { //set HasVm to true if (BlockAddedOrUpdated != null) BlockAddedOrUpdated(item as PPItemBlock); }); else if (item is PPItemNpt) //fire event to add it _dispatcher.Invoke(() => { if (NptAddedOrUpdated != null) NptAddedOrUpdated(item as PPItemNpt); }); } } //sleep if station[st] contains some block if (!_force && !_qThreadAlive) return; Thread.Sleep(10); } } } #endregion #region Delete outside Items //widen the range var actionData2 = new PPRange(actionData.Start.Add(-_rangeMargin), actionData.End.Add(_rangeMargin)); for (int st = 0; st < _stations; st++) { //find outside blocks PPItemBlock[] outsideBlocks; lock (this) { outsideBlocks = _blocks[st].Where(x => !actionData2.IsInRange(x) || x.Id == 0).ToArray(); } foreach (var item in outsideBlocks) { //remove from list lock (this) { _blocks[st].Remove(item); } //remove from Vm _dispatcher.Invoke(() => { if (BlockRemoved != null) BlockRemoved(item); }); } if (!_force && !_qThreadAlive) return; Thread.Sleep(5); //find outside NPTs PPItemNpt[] outsideNpts; lock (this) { outsideNpts = _npts[st].Where(x => !actionData2.IsInRange(x)).ToArray(); } foreach (var item in outsideNpts) { //remove from list lock (this) { _npts[st].Remove(item); } //remove from Vm _dispatcher.Invoke(() => { if (NptRemoved != null) NptRemoved(item); }); } if (!_force && !_qThreadAlive) return; Thread.Sleep(5); } #endregion } catch (Exception e) { if (!LoginInfo.IsDebugMode) return; _qThreadAlive = false; using (var log = new System.IO.StreamWriter(System.IO.Path.Combine(System.IO.Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Soheil"), "Exceptions.log"), append: true)) { log.WriteLine(DateTime.Now.ToShortTimeString()); log.Write("Ex = "); log.WriteLine(e.Message); if (e.InnerException != null) { log.Write("InnerEx = "); log.WriteLine(e.InnerException.Message); } log.Write("Source = "); log.WriteLine(e.Source); log.Write("Trace = "); log.WriteLine(e.StackTrace); log.WriteLine(); log.Close(); } System.Windows.MessageBox.Show("Fatal error.\nfor more info see %appdata%\\Soheil\\Exceptions.Log"); } finally { if(_force) { _force = false; Pause = false; } } }; #endregion #region WorkTimes actions //----------------------- ADD WORK TIME ------------------------------- _actionLoadWorkTimes = (object data) => { //retreive data var actionData = data as PPRange; if (!actionData.IsValidRange()) return; var _workProfilePlanDataService = new DataServices.WorkProfilePlanDataService(); lock (this) { //remove all from Vm _dispatcher.Invoke(() => { if (WorkTimesRemoved != null) WorkTimesRemoved(); }); _shifts.Clear(); } //find workprofiles var workTimes = _workProfilePlanDataService.GetShiftsInRange(actionData.Start, actionData.End) .Where(x => x.Item1.IsOpen); foreach (var tuple in workTimes) { //keep updated with _shiftsDates //if (_shifts.Any(x => x.Id == tuple.Item1.Id && x.DayStart == tuple.Item2)) continue; //create PPItemWorkTime var shiftItem = new PPItemWorkTime(tuple.Item1, tuple.Item2); //add PPItemWorkTime lock (this) { _shifts.Add(shiftItem); } //fire event to add it and its breaks _dispatcher.Invoke(() => { if (WorkTimeAdded != null) WorkTimeAdded(shiftItem); }); } //find day colors var dayColors = _workProfilePlanDataService.GetBusinessDayColorsInRange(actionData.Start, actionData.End).ToArray(); //change colors of Days _dispatcher.Invoke(() => { if (DayColorsUpdated != null) DayColorsUpdated(actionData.Start, dayColors); }); _workProfilePlanDataService.Dispose(); }; #endregion }
/// <summary> /// Reloads day colors and shifts of the selected month /// <para>Also removes other items</para> /// </summary> /// <param name="startOfMonth"></param> public void InitMonth(DateTime startOfMonth) { //time range var end = startOfMonth.AddDays(startOfMonth.GetPersianMonthDays()); var data = new PPRange(startOfMonth, end); //remove other items //add days and shifts Task.Factory.StartNew(_actionLoadWorkTimes, data); }
public void ForceReload() { _qThreadAlive = false; Pause = true; while (_qThread.IsAlive) ; //reset for (int i = 0; i < _stations; i++) { _blocks[i].Clear(); _npts[i].Clear(); } //sync load _force = true; var data = new PPRange(_start, _end); Task.Factory.StartNew(_actionLoadItem, data); }
void _threadStart() { while (_qThreadAlive) { //control the thread while (Pause) { if (!_qThreadAlive) return; Thread.Sleep(200); } //retreive thread-unsafe values PPRange range; lock(_rangeLock) { range = new PPRange(_start, _end); //apply margin if (range.IsValidRange()) range.ApplyMargin(_rangeMargin); } //Load blocks/Npts in range (add/update newer blocks) _actionLoadItem.Invoke(range); Thread.Sleep(500); } }