/// <summary> /// The background worker_ do work. /// </summary> /// <param name="sender"> /// The sender. /// </param> /// <param name="e"> /// The e. /// </param> private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) { AppUtil.NameCurrentThread(this.GetType().Name); Thread.CurrentThread.Priority = ThreadPriority.Lowest; while (this.State == MonitorState.Running) { int canProcessCount = this.BatchProcessSize - this._processQueue.Count; if (canProcessCount > this._pendingQueue.Count) { canProcessCount = this._pendingQueue.Count; } if (canProcessCount > 0) { Console.WriteLine("Starting " + canProcessCount + " requests..."); var itemList = this._pendingQueue.Dequeue(canProcessCount); foreach (FareMonitorRequest request in itemList) { var args = new FareBrowserRequestArg(request); this.OnRequestStarting(args); if (args.Cancel) { continue; } request.Start(); // Start the request and move it to the appropriate queue this._pendingQueue.Remove(request); this._processQueue.Enqueue(request); } } Thread.Sleep(500); } }
/// <summary> /// The on request starting. /// </summary> /// <param name="args"> /// The args. /// </param> protected virtual void OnRequestStarting(FareBrowserRequestArg args) { this._logger.Debug("Starting request for journey: " + args.Request.ShortDetail); if (this.RequestStarting != null) { this.RequestStarting(this, args); } var request = args.Request; if (request.BrowserControl == null) { request.Initialize(); } else { if (request.BrowserControl.RequestState == DataRequestState.Pending) { // Assign the event handler for completed request when the request is starting JourneyBrowserDelegate _requestCompletedHandler = null; _requestCompletedHandler = (b, j) => { try { if (this.State != MonitorState.Running) { return; } lock (this._lockObj) { this.OnRequestCompleted(new FareBrowserRequestArg(request)); this.FinalizeRequest(request); } } finally { request.BrowserControl.GetJourneyCompleted -= _requestCompletedHandler; } }; request.BrowserControl.GetJourneyCompleted += _requestCompletedHandler; } } }
/// <summary> /// The on request stopping. /// </summary> /// <param name="args"> /// The args. /// </param> protected virtual void OnRequestStopping(FareBrowserRequestArg args) { this._logger.Debug("Stopping request: " + args.Request.ShortDetail); if (this.RequestStopping != null) { this.RequestStopping(this, args); } this.FinalizeRequest(args.Request); }
/// <summary> /// The stop. /// </summary> /// <param name="request"> /// The request. /// </param> public void Stop(FareMonitorRequest request) { this._logger.Info("Stopping " + this.GetType().Name); if (this.RequestStopping != null) { FareBrowserRequestArg args = new FareBrowserRequestArg(request); this.OnRequestStopping(args); if (args.Cancel) { return; } } request.Stop(); }
/// <summary> /// The on request completed. /// </summary> /// <param name="args"> /// The args. /// </param> protected virtual void OnRequestCompleted(FareBrowserRequestArg args) { this._logger.Info("Fare request completed: " + args.Request.ShortDetail); if (args.Request.BrowserControl != null && args.Request.BrowserControl.RequestState == DataRequestState.NoData) { this._logger.Info("No data was found!"); } if (this.RequestCompleted != null) { this.RequestCompleted(this, args); } }
/// <summary> /// The live fare monitor_ on request completed. /// </summary> /// <param name="sender"> /// The sender. /// </param> /// <param name="args"> /// The args. /// </param> private void LiveFareMonitor_OnRequestCompleted(FareRequestMonitor sender, FareBrowserRequestArg args) { var request = args.Request; var browser = args.Request.BrowserControl; if (browser == null) { return; } lock (this._notifier) { try { string travelPeriodStr = StringUtil.GetPeriodString(request.DepartureDate, request.ReturnDate); if (browser.RequestState == DataRequestState.NoData) { string header = travelPeriodStr + Environment.NewLine + "From: " + request.Departure + Environment.NewLine + "To: " + request.Destination; this._notifier.Show( "No AirportData", "There is no flight data for this travel period" + Environment.NewLine + header, null, 7000, NotificationType.Warning, true); return; } var route = browser.LastRetrievedRoute; if (route == null || route.Journeys.Count < 1 || route.Journeys[0].Data.Count < 1) { return; } var curJourney = route.Journeys[0]; // Live Monitor: Store the current journey data Journey oldJourney = this._currentMonitorJourneys.FirstOrDefault(j => j.IsSameTrip(curJourney)); var flightData = curJourney.Data[0].Flights; var flightItems = new FlightDisplayItemsCollection(); if (oldJourney == null) { flightItems.AddRange(flightData, FlightStatus.New); } else { var oldFlights = oldJourney.Data[0].Flights; // Compare each flight foreach (Flight currentFlight in flightData) { Flight comparableFlight = oldFlights.FirstOrDefault(f => f.IsSameFlight(currentFlight)); if (comparableFlight == null) { // New flight was found (or first appearance) flightItems.Add(currentFlight, FlightStatus.New, 0); } else { double priceDiff = currentFlight.Price - comparableFlight.Price; if (Math.Abs(priceDiff) > 1) { // Minimum price change is 1 EUR if ((priceDiff > 0 && comparableFlight.Price < this.PriceLimit) // If price was increased and old price is still within price limit || currentFlight.Price <= this.PriceLimit) { // or prices has been decreased enough to the limit flightItems.Add( currentFlight, priceDiff > 0 ? FlightStatus.PriceIncreased : FlightStatus.PriceDecreased, comparableFlight.Price); } } } } } // There are changes in the list of flights if (flightItems.Count > 0) { if (this._fareStorage != null) { try { this._fareStorage.SaveLiveFare(flightItems.Select(i => i.FlightData)); } catch (Exception ex) { AppContext.Logger.ErrorFormat("Could not save live data [{0}]: {1}", travelPeriodStr, ex); this._notifier.Show( travelPeriodStr, "Could not save live data: " + ex.Message, null, 5000, NotificationType.Error, true); } } string currencyCode = curJourney.Data[0].Currency; string currencySymbol = AppContext.MonitorEnvironment.CurrencyProvider.GetCurrencyInfo(currencyCode).Symbol; string header = travelPeriodStr + " (Currency: " + currencyCode + (currencySymbol == currencyCode ? null : " - " + currencySymbol) + ")" + Environment.NewLine + "From: " + request.Departure + Environment.NewLine + "To: " + request.Destination; this._notifier.Show("Fare data was updated", header, flightItems, 5000, NotificationType.Info, true); } if (oldJourney != null) { this._currentMonitorJourneys.Remove(oldJourney); } this._currentMonitorJourneys.Add(curJourney); } finally { // Repeat the process if (this.State == MonitorState.Running && browser.RequestState != DataRequestState.NoData) { args.Request.Reset(); #if !DEBUG // Put some delay if we are not running DEBUG mode var interval = TimeSpan.FromMinutes(1 + PendingRequests.Count); System.Threading.Thread.Sleep(interval); #endif this.Enqueue(args.Request); } } } }
/// <summary> /// The fare export monitor_ on request completed. /// </summary> /// <param name="sender"> /// The sender. /// </param> /// <param name="args"> /// The args. /// </param> private void FareExportMonitor_OnRequestCompleted(FareRequestMonitor sender, FareBrowserRequestArg args) { var browser = args.Request.BrowserControl; if (browser == null) { this._logger.Warn("There is no browser control associated with the request"); return; } TravelRoute route = browser.LastRetrievedRoute; lock (this._lockObj) { var pendingCount = sender.PendingRequests.Count; var processCount = sender.ProcessingRequests.Count; this._logger.DebugFormat("There are {0} pending requests, {1} processing requests", pendingCount, processCount); bool isLastRequest = pendingCount == 0 && processCount == 0; if (browser.RequestState == DataRequestState.Ok && route != null && route.Journeys.Count > 0) { this._cachedRoutes.Add(route); // Cache journeys if (this._cachedRoutes.Count >= CACHE_AMOUNT || isLastRequest) { // Export journeys to file to reduce memory load this.FlushCache(); } } if (isLastRequest) { this._logger.Debug("There is no more active request for the monitor"); this.FinalizeData(); } } }
/// <summary> /// The fare monitor_ request starting. /// </summary> /// <param name="sender"> /// The sender. /// </param> /// <param name="args"> /// The args. /// </param> private void FareMonitor_RequestStarting(FareRequestMonitor sender, FareBrowserRequestArg args) { this.InvokeActionIfNeeded( new Action( () => { FareMonitorRequest request = args.Request; request.Initialize(); // Initialize request here: So that the control is created on the UI thread var browserTabPage = new TabPage( request.DepartureDate.ToString(NamingRule.DATE_FORMAT) + (request.IsRoundTrip ? " - " + request.ReturnDate.ToString(NamingRule.DATE_FORMAT) : string.Empty)); var browser = request.BrowserControl as Control; if (browser != null) { browser.Dock = DockStyle.Fill; browserTabPage.Controls.Add(browser); browserTabPage.BackColor = this.BrowserStartingColor; browserTabPage.ImageIndex = 0; browserTabPage.Tag = request; browserTabPage.ToolTipText = request.Detail; this.fareBrowserTabs.TabPages.Add(browserTabPage); } this.SetStatus(request); })); }
/// <summary> /// The fare monitor_ request completed. /// </summary> /// <param name="sender"> /// The sender. /// </param> /// <param name="args"> /// The args. /// </param> private void FareMonitor_RequestCompleted(FareRequestMonitor sender, FareBrowserRequestArg args) { // This method should be triggered both before stopping the request or after the request is completed var browser = args.Request.BrowserControl; // The browser might be nulled this.InvokeActionIfNeeded( new Action( () => { SwitchButton senderBtn = null; var monType = sender.GetType(); var resultRoute = browser == null ? null : browser.LastRetrievedRoute; if (monType == typeof(FareRequestMonitor)) { // Browser can be nulled if the request was aborted before it is event started if (browser != null && resultRoute != null && !this.btnSummary.Enabled) { this.SetDataProcessor(true); } senderBtn = this.btnShowFare; } else if (monType == typeof(FareExportMonitor)) { senderBtn = this.btnGetFareAndSave; } this.IncreaseProgress(); this.CheckProgress(); if (!this.loadProgress.Visible && senderBtn != null) { var senderMonitor = senderBtn.Tag as FareRequestMonitor; if (senderMonitor == sender && senderBtn.IsSecondState) { senderBtn.IsSecondState = false; // Reset the button after everything is done! } } })); }
/// <summary> /// The close and export_ request completed. /// </summary> /// <param name="sender"> /// The sender. /// </param> /// <param name="args"> /// The args. /// </param> private void CloseAndExport_RequestCompleted(FareRequestMonitor sender, FareBrowserRequestArg args) { this.SafeInvoke( new Action( () => { this.FareMonitor_RequestCompleted(sender, args); var browserControl = args.Request.BrowserControl as WebFareBrowserControl; var tabPageObj = browserControl.Parent as TabPage; if (tabPageObj != null) { this.fareBrowserTabs.TabPages.Remove(tabPageObj); tabPageObj.Dispose(); } if (sender.State == MonitorState.Stopped && this.chkExitAfterDoneStrip.ControlItem.Checked) { Environment.Exit(0); } })); }
/// <summary> /// The show fare_ request completed. /// </summary> /// <param name="sender"> /// The sender. /// </param> /// <param name="args"> /// The args. /// </param> private void ShowFare_RequestCompleted(FareRequestMonitor sender, FareBrowserRequestArg args) { this.InvokeActionIfNeeded( new Action( () => { var fareBrowserObj = args.Request.BrowserControl as WebFareBrowserControl; if (fareBrowserObj.IsDestructed() || fareBrowserObj.LastRequestInitiatedDate != args.RequestInitiatedDate || fareBrowserObj.RequestState == DataRequestState.Pending) { return; } var browserTabPage = fareBrowserObj.Parent as TabPage; if (browserTabPage == null) { return; } if (fareBrowserObj.RequestState == DataRequestState.Pending || fareBrowserObj.RequestState == DataRequestState.Requested) { browserTabPage.BackColor = this.BrowserStartingColor; } else if (fareBrowserObj.RequestState == DataRequestState.Ok) { browserTabPage.BackColor = this.BrowserSuccessColor; } else { browserTabPage.BackColor = this.BrowserFailedColor; } if (this.chkAutoFocusTabStrip.ControlItem.Checked) { this.fareBrowserTabs.SelectedTab = browserTabPage; } this.FareMonitor_RequestCompleted(sender, args); })); }
/// <summary> /// The live fare_ request starting. /// </summary> /// <param name="sender"> /// The sender. /// </param> /// <param name="args"> /// The args. /// </param> private void LiveFare_RequestStarting(FareRequestMonitor sender, FareBrowserRequestArg args) { args.Request.Initialize(); var monitor = sender as LiveFareMonitor; monitor.PriceLimit = (double)this.numPriceLimit.Value; }