/// <summary> /// Call all subscribers in parallel and wait for all to complete. /// </summary> /// <typeparam name="T">The type of the results.</typeparam> /// <param name="ServerTimestamp">The timestamp of the event.</param> /// <param name="OCPIAPI">The sending OCPI/HTTP API.</param> /// <param name="Request">The incoming request.</param> /// <param name="Response">The outgoing response.</param> /// <param name="VerifyResult">A delegate to verify and filter results.</param> /// <param name="Timeout">A timeout for this operation.</param> /// <param name="DefaultResult">A default result in case of errors or a timeout.</param> public Task <T> WhenFirst <T>(DateTime ServerTimestamp, HTTPAPI OCPIAPI, OCPIRequest Request, OCPIResponse Response, Func <T, Boolean> VerifyResult, TimeSpan?Timeout = null, Func <TimeSpan, T> DefaultResult = null) { #region Data List <Task> _invocationList; Task WorkDone; Task <T> Result; DateTime StartTime = DateTime.UtcNow; Task TimeoutTask = null; #endregion lock (subscribers) { _invocationList = subscribers. Select(callback => callback(ServerTimestamp, OCPIAPI, Request, Response)). ToList(); if (Timeout.HasValue) { _invocationList.Add(TimeoutTask = Task.Run(() => System.Threading.Thread.Sleep(Timeout.Value))); } } do { try { WorkDone = Task.WhenAny(_invocationList); _invocationList.Remove(WorkDone); if (WorkDone != TimeoutTask) { Result = WorkDone as Task <T>; if (Result != null && !EqualityComparer <T> .Default.Equals(Result.Result, default(T)) && VerifyResult(Result.Result)) { return(Result); } } } catch (Exception e) { DebugX.LogT(e.Message); WorkDone = null; } }while (!(WorkDone == TimeoutTask || _invocationList.Count == 0)); return(Task.FromResult(DefaultResult(DateTime.UtcNow - StartTime))); }
private async Task SendNotifications2(Object State) { var LockTaken = await SendNotificationsLock.WaitAsync(0).ConfigureAwait(false); try { if (LockTaken) { //var NotificationMessages = UsersAPI.NotificationMessages. // Where (notificationMessage => notificationMessage.Timestamp > LatestNotificationTimestamp). // ToArray(); //if (NotificationMessages.Length > 0) //{ // LatestNotificationTimestamp = NotificationMessages. // Max (notificationMessage => notificationMessage.Timestamp); // await SendNotifications(NotificationMessages. // Select(notificationMessage => notificationMessage.Value)); //} } } catch (Exception e) { while (e.InnerException != null) { e = e.InnerException; } //DebugX.LogT(GetType().Name + ".SendNotifications '" + Id + "' led to an exception: " + e.Message + Environment.NewLine + e.StackTrace); //OnWWCPCPOAdapterException?.Invoke(Timestamp.Now, // this, // e); } finally { if (LockTaken) { SendNotificationsLock.Release(); // DebugX.LogT("SendNotificationsLock released!"); } else { DebugX.LogT("SendNotificationsLock exited!"); } } }
private async Task FlushChargeDetailRecords2(Object State) { var LockTaken = await FlushChargeDetailRecordsLock.WaitAsync(0); try { if (LockTaken) { //DebugX.LogT("FlushChargeDetailRecordsLock entered!"); if (SkipFlushChargeDetailRecordsQueues()) { return; } #region Send StartEvent... var StartTime = DateTime.UtcNow; FlushChargeDetailRecordsQueuesStartedEvent?.Invoke(this, StartTime, FlushEVSEFastStatusEvery, _CDRRunId); #endregion await FlushChargeDetailRecordsQueues(); #region Send Finished Event... var EndTime = DateTime.UtcNow; FlushChargeDetailRecordsQueuesFinishedEvent?.Invoke(this, StartTime, EndTime, EndTime - StartTime, FlushEVSEFastStatusEvery, _CDRRunId); #endregion _CDRRunId++; } } catch (Exception e) { while (e.InnerException != null) { e = e.InnerException; } DebugX.LogT(GetType().Name + ".FlushChargeDetailRecords '" + Id + "' led to an exception: " + e.Message + Environment.NewLine + e.StackTrace); OnWWCPCPOAdapterException?.Invoke(DateTime.UtcNow, this, e); } finally { if (LockTaken) { FlushChargeDetailRecordsLock.Release(); DebugX.LogT("FlushChargeDetailRecordsLock released!"); } else { DebugX.LogT("FlushChargeDetailRecordsLock exited!"); } } }
private void ImporterRun(Object Status) { Thread.CurrentThread.Priority = ThreadPriority.BelowNormal; if (Monitor.TryEnter(ImporterRunLock)) { #region Debug info #if DEBUG DebugX.LogT("WWCP importer '" + Id + "' started!"); var StartTime = DateTime.UtcNow; #endif #endregion try { #region Remove ForwardingInfos older than 7 days... //var Now = DateTime.UtcNow; //var ToRemove = _AllForwardingInfos. // Where (ForwardingInfo => ForwardingInfo.Value.LastTimeSeen + TimeSpan.FromDays(7) < Now). // Select(ForwardingInfo => ForwardingInfo.Key). // ToList(); //ToRemove.ForEach(ForwardingInfo => _AllForwardingInfos.Remove(ForwardingInfo)); #endregion GetData(DateTime.UtcNow, this, DateTime.UtcNow, _LastRunId++, DNSClient). ContinueWith(ImporterTask => { // Check for null... if (!EqualityComparer <T> .Default.Equals(ImporterTask.Result, default(T))) { //ToDo: Handle XML parser exceptions... AddOrUpdateForwardingInfos(CreateForwardingTable(this, ImporterTask.Result, AllChargingStationOperators, GetChargingStationOperators, GetDefaultChargingStationOperator)); } return(ImporterTask.Result); }). ContinueWith(ImporterTask => { // Check for null... if (!EqualityComparer <T> .Default.Equals(ImporterTask.Result, default(T))) { //if (_ImportedData.Count >= MaxNumberOfCachedDataImports) //{ // var succ = _ImportedData.Remove(_ImportedData[0]); // DebugX.LogT("Importer Count = " + _ImportedData.Count + " " + succ); //} //// Save the imported data for later review... //_ImportedData.Add(new Timestamped<T>(ImporterTask.Result)); // Update ForwardingInfos OnEveryRun?.Invoke(this, ImporterTask); } }). Wait(); #region Debug info #if DEBUG OnFinished?.Invoke(DateTime.UtcNow, this, "WWCP importer '" + Id + "' finished after " + (DateTime.UtcNow - StartTime).TotalSeconds + " seconds!"); #endif #endregion } catch (Exception e) { while (e.InnerException != null) { e = e.InnerException; } DebugX.LogT("WWCP importer '" + Id + "' led to an exception: " + e.Message + Environment.NewLine + e.StackTrace); } finally { Monitor.Exit(ImporterRunLock); } } else { DebugX.LogT("WWCP importer '" + Id + "' skipped!"); } }
private void ImportEvery(Object Status) { Thread.CurrentThread.Priority = ThreadPriority.BelowNormal; if (Monitor.TryEnter(UpdateEVSEDataAndStatusLock)) { #region Debug info #if DEBUG // DebugX.LogT("WWCP importer '" + Id + "' started!"); var StopWatch = new Stopwatch(); StopWatch.Start(); #endif #endregion try { #region Remove ForwardingInfos older than 7 days... //var Now = DateTime.Now; //var ToRemove = _AllForwardingInfos. // Where (ForwardingInfo => ForwardingInfo.Value.LastTimeSeen + TimeSpan.FromDays(7) < Now). // Select(ForwardingInfo => ForwardingInfo.Key). // ToList(); //ToRemove.ForEach(ForwardingInfo => _AllForwardingInfos.Remove(ForwardingInfo)); #endregion DownloadData(DateTime.Now, "1", _DNSClient). ContinueWith(ImporterTask => { // Save the imported data for later review... _ImportedData.Add(new Timestamped <T>(ImporterTask.Result.Content)); if (_ImportedData.Count > _MaxNumberOfCachedDataImports) { _ImportedData.Remove(_ImportedData.First()); } // Mark ForwardingInfos as 'OutOfService', to detect which are no longer within the XML... lock (_AllForwardingInfos) { _AllForwardingInfos.Values.ForEach(FwdInfo => FwdInfo.OutOfService = true); } // Update ForwardingInfos var OnEveryRunLocal = OnEveryRun; if (OnEveryRunLocal != null) { OnEveryRunLocal(this, ImporterTask); } }). Wait(); #region Debug info #if DEBUG StopWatch.Stop(); // DebugX.LogT("WWCP importer '" + Id + "' finished after " + StopWatch.Elapsed.TotalSeconds + " seconds!"); #endif #endregion } catch (Exception e) { while (e.InnerException != null) { e = e.InnerException; } DebugX.LogT("WWCP importer '" + Id + "' led to an exception: " + e.Message + Environment.NewLine + e.StackTrace); } finally { Monitor.Exit(UpdateEVSEDataAndStatusLock); } } // else // DebugX.LogT("WWCP importer '" + Id + "' skipped!"); }