Summary description for ParserWorker.
Наследование: IFWDisposable
Пример #1
0
        /// -----------------------------------------------------------------------------------
        /// <summary>
        /// Initializes a new instance of the <see cref="ParserScheduler"/> class.
        /// </summary>
        /// -----------------------------------------------------------------------------------
        public ParserScheduler(FdoCache cache, IdleQueue idleQueue)
        {
            if (cache == null)
            {
                throw new ArgumentNullException("cache");
            }

            Trace.WriteLineIf(m_tracingSwitch.TraceInfo, "ParserScheduler(): CurrentThreadId = " + Win32.GetCurrentThreadId());

            m_cache = cache;

            switch (m_cache.LanguageProject.MorphologicalDataOA.ActiveParser)
            {
            case "XAmple":
                m_parserWorker = new XAmpleParserWorker(cache, HandleTaskUpdate, idleQueue);
                break;

            case "HC":
                m_parserWorker = new HCParserWorker(cache, HandleTaskUpdate, idleQueue);
                break;

            default:
                throw new InvalidOperationException("The language project is set to use an unrecognized parser.");
            }
            m_parserWorker.ParseFiler.WordformUpdated += ParseFiler_WordformUpdated;

            m_thread = new ConsumerThread <ParserPriority, ParserWork>(Work)
            {
                IsBackground = true
            };
            ReloadGrammarAndLexicon();
            m_thread.Start();
        }
Пример #2
0
        /// -----------------------------------------------------------------------------------
        /// <summary>
        /// Initializes a new instance of the <see cref="ParserScheduler"/> class.
        /// </summary>
        /// -----------------------------------------------------------------------------------
        public ParserScheduler(FdoCache cache, IdleQueue idleQueue, string dataDir)
        {
            m_parserWorker = new ParserWorker(cache, HandleTaskUpdate, idleQueue, dataDir);
            m_parserWorker.ParseFiler.WordformUpdated += ParseFiler_WordformUpdated;

            m_thread = new ConsumerThread <ParserPriority, ParserWork>(Work);
            ReloadGrammarAndLexicon();
            m_thread.Start();
        }
Пример #3
0
        protected override void DisposeManagedResources()
        {
            m_thread.Stop();
            m_thread.Dispose();

            if (m_parserWorker != null)
            {
                m_parserWorker.ParseFiler.WordformUpdated -= ParseFiler_WordformUpdated;
                m_parserWorker.Dispose();
                m_parserWorker = null;
            }

            if (m_TaskReport != null)
            {
                m_TaskReport.Dispose();
                m_TaskReport = null;
            }
        }
Пример #4
0
		protected override void DisposeManagedResources()
		{
			m_thread.Stop();
			m_thread.Dispose();

			if (m_parserWorker != null)
			{
				m_parserWorker.ParseFiler.WordformUpdated -= ParseFiler_WordformUpdated;
				m_parserWorker.Dispose();
				m_parserWorker = null;
			}

			if (m_TaskReport != null)
			{
				m_TaskReport.Dispose();
				m_TaskReport = null;
			}
		}
Пример #5
0
		/// -----------------------------------------------------------------------------------
		/// <summary>
		/// Initializes a new instance of the <see cref="ParserScheduler"/> class.
		/// </summary>
		/// -----------------------------------------------------------------------------------
		public ParserScheduler(FdoCache cache, IdleQueue idleQueue, string dataDir)
		{
			m_parserWorker = new ParserWorker(cache, HandleTaskUpdate, idleQueue, dataDir);
			m_parserWorker.ParseFiler.WordformUpdated += ParseFiler_WordformUpdated;

			m_thread = new ConsumerThread<ParserPriority, ParserWork>(Work) {IsBackground = true};
			ReloadGrammarAndLexicon();
			m_thread.Start();
		}
Пример #6
0
		private void MainLoop(WaitHandle[] waitEvents, bool bIdle)
		{
			try
			{
				while (true)
				{
					//				DebugMsg("parser worker thread loop");
					// Look for STOP event or real work
					int waitIndex = WaitHandle.WaitAny(waitEvents, m_waitTime, false);

					// handle the STOP event without doing other work
					if (waitIndex == 0)
					{
						try
						{
							if (!Monitor.TryEnter(this))
							{
								TraceMsg(lockingSwitch.TraceInfo, ">>>>>>>*****  collision locking parser thread A********<<<<<<<<<<<");
								Monitor.Enter(this);
							}
							if (m_parserWorker != null)
							{
								m_parserWorker.Dispose();
								m_parserWorker = null;
							}
							if (m_sqlConnection != null)
							{
								m_sqlConnection.Close();
								m_sqlConnection = null;
							}
							break;
						}
						finally
						{
							Monitor.Exit(this);
						}
					}

					// handle the Paused 'state'
					if (IsPaused)
					{
						Thread.Sleep(250);	// give it a quarter second to become unpaused
						continue;	// Paused, continue allows checking for Stop event
					}

					// not Stopped or Paused, see if the Grammar needs to be updated
					bool notYetLoaded;
					try
					{
						if (!Monitor.TryEnter(this))
						{
							TraceMsg(lockingSwitch.TraceInfo, ">>>>>>>*****  collision locking parser thread B********<<<<<<<<<<<");
							Monitor.Enter(this);
						}
						notYetLoaded = m_lastGrammarUpdateStamp.Empty;
					}
					finally
					{
						Monitor.Exit(this);
					}
					if (notYetLoaded)
					{
						LoadGrammarAndLexicon(NeedsUpdate.GrammarAndLexicon);
						bIdle = false;
					}
					else
					{
						NeedsUpdate updateNeeded = GetGrammarOrLexiconNeedsUpdate();
						LoadGrammarAndLexicon(updateNeeded);
						if (updateNeeded != NeedsUpdate.Nothing)
							bIdle = false; // now there is something to do
					}

					// See if none of our previous events have been fired
					if (waitIndex == WaitHandle.WaitTimeout)
					{
						// switch back to lower priority thread, if not already
						if (Thread.CurrentThread.Priority != ThreadPriority.BelowNormal)
						{
							Thread.CurrentThread.Priority = ThreadPriority.BelowNormal;
							Trace.WriteLineIf(tracingSwitch.TraceInfo, "=======>Scheduler Thread: " + Thread.CurrentThread.ManagedThreadId.ToString() + " setting priority to BelowNormal");
						}

						// still nothing pending...
						if (!bIdle)
						{
							//Trace.WriteLine("MainLoop: Begin Show Idle, WaitHandle.WaitTimeout");
							new TaskReport(ParserCoreStrings.ksIdle_,
								new TaskUpdateEventHandler(this.HandleTaskUpdate));
							//Trace.WriteLine("MainLoop: End   Show Idle, WaitHandle.WaitTimeout");
							bIdle = true;	// this will keep us from reporting 'idle' constantly
						}
						continue;
					}
					// See if Try a Word is running and there are still words in a queue, but we're not parsing a word for Try a Word
					if (m_fTryAWordDialogRunning && waitIndex == 2)
					{
						if (!bIdle)
						{
							//Trace.WriteLine("MainLoop: Begin Show Idle, Try A Word");
							new TaskReport(ParserCoreStrings.ksIdle_,
								new TaskUpdateEventHandler(this.HandleTaskUpdate));
							//Trace.WriteLine("MainLoop: End   Show Idle, Try A Word");
							bIdle = true;	// this will keep us from reporting 'idle' constantly
						}
						continue;
					}
					bIdle = false;	// turn off idle flag

					DoWordEvent(waitIndex);
				}
			}
			catch (System.Threading.ThreadInterruptedException)
			{
				//m_caughtException = error;
			}
			catch (System.Threading.ThreadAbortException)
			{
				//m_caughtException = error;
			}
		}
Пример #7
0
		/// <summary>
		/// Executes in two distinct scenarios.
		///
		/// 1. If disposing is true, the method has been called directly
		/// or indirectly by a user's code via the Dispose method.
		/// Both managed and unmanaged resources can be disposed.
		///
		/// 2. If disposing is false, the method has been called by the
		/// runtime from inside the finalizer and you should not reference (access)
		/// other managed objects, as they already have been garbage collected.
		/// Only unmanaged resources can be disposed.
		/// </summary>
		/// <param name="disposing"></param>
		/// <remarks>
		/// If any exceptions are thrown, that is fine.
		/// If the method is being done in a finalizer, it will be ignored.
		/// If it is thrown by client code calling Dispose,
		/// it needs to be handled by fixing the bug.
		///
		/// If subclasses override this method, they should call the base implementation.
		/// </remarks>
		private void Dispose(bool disposing)
		{
			//Debug.WriteLineIf(!disposing, "****************** " + GetType().Name + " 'disposing' is false. ******************");
			//Debug.Assert(disposing, "Don't even think about not disposing this object properly!");
			// Must not be run more than once.
			if (m_isDisposed)
				return;

			if (disposing)
			{
				// Dispose managed resources here.
				if (m_consumerThread != null)
				{
					//REVIEW: not sure if this is right
					//				if(this.IsPaused)
					//					this.Resume();

					// Notify the parser to quit if it's running.  See LT-3546 for motivation.
					if (m_parserWorker != null)
					{
						int idThread = m_parserWorker.ThreadId;
						Trace.WriteLineIf(tracingSwitch.TraceInfo, "ParserScheduler.Dispose(true): m_parserWorker.ThreadId = " + idThread.ToString() +
							", m_consumerThread.ManagedThreadId = " + m_consumerThread.ManagedThreadId +
							", GetCurrentThreadId() = " + Win32.GetCurrentThreadId().ToString());
						if (idThread != 0)
						{
							bool fOk;
							fOk = Win32.PostThreadMessage(idThread, (int)Win32.WinMsgs.WM_USER,
								(uint)Win32.WinMsgs.WM_QUIT, (uint)idThread);
							if (!fOk)
								Trace.WriteLineIf(tracingSwitch.TraceError, "ParserScheduler.Dispose(true): Win32.PostThreadMessage() to stop thread failed!??");
						}
					}
					// REVIEW DanH (RandyR): Why is is paused only to be resumed?
					AttemptToPause();
					//un-pause if necessary
					Resume();
					//note that this is a polite interruption... it will only stop the thread if it is sleeping
					//m_consumerThread.Interrupt();

					if (m_consumerThread.IsAlive)
					{
						m_consumerThread.Priority = ThreadPriority.AboveNormal;	// make sure we are normal priority to get chance to run
						m_consumerThread.Interrupt();
					}
					m_StopEvent.Set();		// ready to stop now, signal STOP event
					// If the DB is still working, then it will pull the plug on the thread.
					// I (RandyR) reset the timeout for the DB to be 30 seconds, since some actions took longer than the
					// previous limit of 10 seconds.
					// Therefore, I bumped this wait from 10 to 45 seconds.
					// Even 45 seconds isn't long enough when it is dumping the grammar and lexicon, for larger data sets.
					if (m_consumerThread.IsAlive == false || m_consumerThread.Join(new TimeSpan(0,0,45)))	// wait up to 45 seconds, since the DQ connection mya be waiting for 30 seconds.
					{
						// consumer thread exited
						Trace.WriteLineIf(tracingSwitch.TraceInfo, "==== ParserScheduler thread Successfully shutdown.");
					}
					else
					{
						Trace.WriteLineIf(tracingSwitch.TraceError, "**** ERROR : ParserScheduler Thread didn't shut down, Aborting.");
						try
						{
							m_consumerThread.Abort();
						}
						catch (ThreadAbortException)
						{
							// Eat the ThreadAbortException exception, since it isn't fatal.
						}
						finally
						{
							if (m_consumerThread.Join(new TimeSpan(0,0,10))== false)	// wait up to 10 more seconds
							{
								Trace.WriteLineIf(tracingSwitch.TraceError, "**** ERROR : Abort didn't shutdown.");
							}
							// Both of these should have been Closed/Disposed & the variables set to null by now,
							// IF the thread had shut down properly, that is.
							if (m_sqlConnection != null)
							{
								Trace.WriteLineIf(tracingSwitch.TraceError, "Shut down connection by brute force.");
								m_sqlConnection.Close();
								m_sqlConnection.Dispose();
							}
							if (m_parserWorker != null)
							{
								Trace.WriteLineIf(tracingSwitch.TraceError, "Disposing Worker bee by brute force.");
								m_parserWorker.Dispose();
							}
						}
					}
				}
			}
			// Dispose unmanaged resources here, whether disposing is true or false.
			m_caughtException = null;
			m_sqlConnection = null;
			m_parserWorker = null;
			m_consumerThread = null;
			m_lastGrammarUpdateStamp = null;
			m_server = null;
			m_database = null;
			m_LangProject = null;

			m_isDisposed = true;
		}
Пример #8
0
		/// -----------------------------------------------------------------------------------
		/// <summary>
		/// Initializes a new instance of the <see cref="ParserScheduler"/> class.
		/// </summary>
		/// -----------------------------------------------------------------------------------
		public void Init(string server, string database, string LangProject)
		{
			DebugMsg("ParserScheduler constructor is being called");
			Trace.WriteLineIf(tracingSwitch.TraceInfo, "ParserScheduler(): CurrentThreadId = " + Win32.GetCurrentThreadId().ToString());

			m_server = server;
			m_database = database;
			m_LangProject = LangProject;
			m_paused = false;
			m_sqlConnection = new SqlConnection(GetConnectionString());
			m_sqlConnection.Open();

			SqlCommand command = m_sqlConnection.CreateCommand();
			command.CommandText = "select top 1 ParserParameters from MoMorphData";
			XmlDocument doc = new XmlDocument();
			doc.LoadXml(((string)command.ExecuteScalar()).Trim());

			XmlNode parserNode = doc.SelectSingleNode("/ParserParameters/ActiveParser");
			m_parser = parserNode == null ? "XAmple" : parserNode.InnerText;

			// could use reflection to create the correct parser worker, then this switch statement
			// would not need to be updated for each parser, probably not a big deal for now
			switch (m_parser)
			{
				case "XAmple":
					m_parserWorker = new XAmpleParserWorker(m_sqlConnection, m_database, m_LangProject,
						new TaskUpdateEventHandler(this.HandleTaskUpdate));
					break;

				case "HC":
					m_parserWorker = new HCParserWorker(m_sqlConnection, m_database, m_LangProject,
						new TaskUpdateEventHandler(this.HandleTaskUpdate));
					break;
			}

			m_lastGrammarUpdateStamp = new TimeStamp();
			m_fForceGrammarOrLexiconNeedsUpdatingCheck = false;

			m_StopEvent = new ManualResetEvent(false);
			m_PauseEvent = new ManualResetEvent(false);
			m_QueueEvent = new ManualResetEvent(false);
			m_TryAWordEvent = new ManualResetEvent(false);
			m_waitTime = new TimeSpan(0, 0, 1);

			m_lowQueue = new M3ParserWordformQueue();
			m_mediumQueue = new M3ParserWordformQueue();
			m_highQueue = new M3ParserWordformQueue();
			//			m_traceQueue = new M3ParserWordformQueue();

			m_consumerThread = new Thread(new ThreadStart(this.ConsumerThreadStart));
			m_consumerThread.Priority = ThreadPriority.BelowNormal;
			m_consumerThread.IsBackground = true; // Can't prevent owning app from terminating.
			m_consumerThread.Name = "Parser scheduler-worker";
			m_consumerThread.SetApartmentState(ApartmentState.STA); // do before starting - DH
			m_consumerThread.CurrentUICulture = System.Threading.Thread.CurrentThread.CurrentUICulture;
			m_consumerThread.Start();
			m_cref = 1;
		}