public void ReadParallel(Action <PortionChunkReader[]> callback) { const int cores = 4; var threads = new ThreadWrapper[cores]; var chunkReaders = new PortionChunkReader[cores]; for (var i = 0; i < cores; i++) { chunkReaders[i] = new PortionChunkReader(i); threads[i] = new ThreadWrapper(ReadDataFromSource); threads[i].OnError += (source, e) => { foreach (var t in threads) { if (Equals(t, source)) { continue; } t.BaseThread.Interrupt(); } }; } for (var i = 0; i < cores; i++) { threads[i].Start(chunkReaders[i]); } callback(chunkReaders); }
private void GetThreadName(ThreadWrapper threadWrapper, ValueWrapper threadObject, NuGenFrameRefresher threadActiveFrameRefresher) { List <ModuleWrapper> modules = threadWrapper.FindModulesByName(GetThreadNameMethod.BaseTypeDefinition.ModuleScope.Assembly.FileName); if (modules.Count == 1) { ModuleWrapper module = modules[0]; FunctionWrapper getThreadNameFunction = module.GetFunction(GetThreadNameMethod.Token); List <ValueWrapper> arguments = new List <ValueWrapper>(1); arguments.Add(threadObject); NuGenEvaluationHandler methodCaller = new NuGenEvaluationHandler(threadActiveFrameRefresher); NuGenBaseEvaluationResult evaluationResult = methodCaller.CallFunction(getThreadNameFunction, arguments); if (evaluationResult.IsSuccessful) { if (evaluationResult.Result != null && (CorElementType)evaluationResult.Result.ElementType == CorElementType.ELEMENT_TYPE_STRING) { ValueWrapper dereferencedResult = evaluationResult.Result.DereferenceValue(); if (dereferencedResult != null) { EvaluatedThreadName = NuGenHelperFunctions.ShowEscapeCharacters(dereferencedResult.GetStringValue(), true); } } } } }
private void lbRunning_DoubleClick(object sender, EventArgs e) { ThreadWrapper wrapper = lbRunning.SelectedItem as ThreadWrapper; wrapper.Stop(true); lbRunning.Items.Remove(wrapper); }
/// <summary> /// Setup custom rules overriding autowired ones, for example in cases /// where an interface has multiple implementations, and cases where /// a singleton is preferred to new instances. /// </summary> private static void SetupCustomRules(ContainerBuilder builder) { // Make sure the configuration is read only once. IConfig config = new Config(new ConfigData(new Logger(Uptime.ProcessId))); builder.RegisterInstance(config).As <IConfig>().SingleInstance(); // Service configuration is generated by the entry point, so we // prepare the instance here. builder.RegisterInstance(config.LoggingConfig).As <ILoggingConfig>().SingleInstance(); builder.RegisterInstance(config.ServicesConfig).As <IServicesConfig>().SingleInstance(); builder.RegisterInstance(config.BlobStorageConfig).As <IBlobStorageConfig>().SingleInstance(); // Instantiate only one logger var logger = new Logger(Uptime.ProcessId, config.LoggingConfig); builder.RegisterInstance(logger).As <ILogger>().SingleInstance(); var threadWrapper = new ThreadWrapper(); // Auth and CORS setup Auth.Startup.SetupDependencies(builder, config); // By default the DI container create new objects when injecting // dependencies. To improve performance we reuse some instances, // for example to reuse IoT Hub connections, as opposed to creating // a new connection every time. //builder.RegisterType<Foo>().As<IFoo>().SingleInstance(); ICloudStorageWrapper cloudStorageWrapper = new CloudStoragWrapper(); IBlobStorageHelper blobStorageHelper = new BlobStorageHelper(config.BlobStorageConfig, cloudStorageWrapper, logger); IFileWrapper fileWrapper = new FileWrapper(); IDeviceGroupsWriter deviceGroupsWriter = new DeviceGroupsWriter(config.BlobStorageConfig, blobStorageHelper, fileWrapper, logger); builder.RegisterInstance(deviceGroupsWriter).As <IDeviceGroupsWriter>().SingleInstance(); IHttpClient httpClient = new HttpClient(logger); IDevicesClient devicesClient = new DevicesClient(httpClient, config.ServicesConfig, logger); builder.RegisterInstance(devicesClient).As <IDevicesClient>().SingleInstance(); IDeviceGroupsClient deviceGroupsClient = new DeviceGroupsClient( httpClient, devicesClient, config.ServicesConfig, logger, threadWrapper); builder.RegisterInstance(deviceGroupsClient).As <IDeviceGroupsClient>().SingleInstance(); // Event Hub Classes IEventProcessorHostWrapper eventProcessorHostWrapper = new EventProcessorHostWrapper(); builder.RegisterInstance(eventProcessorHostWrapper).As <IEventProcessorHostWrapper>().SingleInstance(); IEventHubStatus eventHubStatus = new EventHubStatus(); builder.RegisterInstance(eventHubStatus).As <IEventHubStatus>().SingleInstance(); IEventProcessorFactory eventProcessorFactory = new DeviceEventProcessorFactory(eventHubStatus, config.ServicesConfig, logger); builder.RegisterInstance(eventProcessorFactory).As <IEventProcessorFactory>().SingleInstance(); }
private void btnCreateThread_Click(object sender, EventArgs e) { countThreadWrapper++; ThreadWrapper threadWrapper = new ThreadWrapper($"Thread #{countThreadWrapper}", semaphore); lbCreated.Items.Add(threadWrapper); }
public void Start() { lock (this) { if (hasBeenStarted) { throw new InvalidOperationException("Pool has already been started."); } hasBeenStarted = true; // Check to see if there were already items posted to the queue // before Start was called. If so, reset their timestamps to // the current time. // if (requestQueue.Count > 0) { ResetWorkRequestTimes(); } for (int n = 0; n < initialThreadCount; n++) { ThreadWrapper thread = new ThreadWrapper(this, true, threadPriority, string.Format("{0} (static)", threadPoolName)); thread.Start(); } if (Started != null) { Started(); // TODO: reconsider firing this event while holding the lock... } } }
private Threads ReturnProducts(List <Product> list) { try { var wrap = new ThreadWrapper(); var result = new Threads(); List <EndProduct> endProducts = new List <EndProduct>(); foreach (var item in list) { var newList = new List <string>(); var endProduct = new EndProduct(); endProduct.Title = item.Title; foreach (var comment in item.Comments) { newList.Add(comment.Comment); } endProduct.Comments = newList; endProducts.Add(endProduct); var results = new List <EndProduct>(); foreach (var product in endProducts) { results.Add(product); } wrap.Threads = results; } result.ThreadWrapper = wrap; return(result); } catch (Exception) { _logger.LogCritical("Failed To Return Product From Reddit"); throw; } }
public override void Connect(ServerInfo serverInfo) { if (Connected) { throw new ProtocolException("Connection error: Already connected to server."); } foreach (var modAPI in ModAPIs) { modAPI.OnConnect(serverInfo); } // -- Connect to server. Stream.Connect(serverInfo.Address.IP, serverInfo.Address.Port); // -- Begin data reading. if (ReadThread != null && ReadThread.IsRunning) { throw new ProtocolException("Connection error: Thread already running."); } else { ReadThread = ThreadWrapper.Create(ReadCycle); ReadThread.IsBackground = true; ReadThread.Name = "PacketReaderThread"; ReadThread.Start(); } }
// Try to avoid deadlock on Select method (sometimes infinite loop inside ContainerControl.UpdateFocusedControl) public static void SafeSelect(this Control control) { if (!control.CanSelect) { return; } // using Dispose to call ResetAbort always, if it was requested, even if no exception is thrown yet using (var threadWrapper = new ThreadWrapper(Thread.CurrentThread)) { try { using (CreateTimer(threadWrapper)) { control.Select(); } } catch (ThreadAbortException ex) { threadWrapper.ResetAbort(); Logger.WarnException(AbortReason, ex); } } }
public static ThreadWrapper StartNew(Action action) { var thread = new ThreadWrapper(action); thread.Start(); return(thread); }
public IActionResult Threads() { // make sure user is logged in string userEmail = HttpContext.Session.GetString("logged_in_user"); if (userEmail == null) { return(RedirectToAction("Index")); } User loggedInUser = _context.Users .Where(u => u.Email == userEmail) .SingleOrDefault(); List <Thread> threads = _context.Threads .Include(t => t.User) .Include(t => t.Messages) .ThenInclude(m => m.User) .OrderBy(m => m.CreatedAt) .ToList(); ThreadWrapper wrapper = new ThreadWrapper() { LoggedInUser = loggedInUser, Threads = threads }; return(View("threads", wrapper)); }
private void FormMain_FormClosing(object sender, FormClosingEventArgs e) { for (int i = 0; i < lbRunning.Items.Count; i++) { ThreadWrapper wrapper = lbRunning.Items[i] as ThreadWrapper; wrapper.Kill(); } }
private static void WorkDone(ThreadWrapper wrapper) { lock (__lockObject) { _availableThreads.Enqueue(wrapper); } _availableEventHandler.Set(); }
void SpawnThreads() { ThreadWrapper tw = new ThreadWrapper(); ParameterizedThreadStart ps = new ParameterizedThreadStart(ThreadWorker); tw.m_thread = new Thread(ps); tw.m_thread.Start(tw); }
protected TcpServer(int port) { Port = port; _listener = new TcpListener(IPAddress.Any, port); _threadWrapper = new ThreadWrapper { DoWork = WaitForConnections }; }
private void ChangeCurrentThread(ThreadWrapper thread) { NuGenUIHandler.Instance.ClearDebugPanels(true); NuGenUIHandler.Instance.ClearUserWarning(); NuGenUIHandler.Instance.ClearCodeDisplayers(true); NuGenDebugEventHandler.Instance.EventObjects.Thread = thread; NuGenDebugEventHandler.Instance.DisplayAllInformation(); }
private static IDisposable CreateTimer(ThreadWrapper threadWrapper) { if (!LongOperationSettings.DetectDeadlocks) { return(null); } return(new Timer(CancelSelect, threadWrapper, TimeSpan.FromSeconds(1), Timeout.InfiniteTimeSpan)); }
private void InitializeThread() { _receivingThread = new ThreadWrapper { DoWork = WaitForIncomingMessage, OnExit = OnExitIncomingMessageLoop, OnError = HandleError }; }
internal static void ForEach <TSource>(string parallelizationPointName, IEnumerable <TSource> source, Action <TSource> body) { Verify.ArgumentNotNull(source, "source"); if (source is TSource[]) { int elementsCount = (source as TSource[]).Length; if (elementsCount == 0) { return; } if (elementsCount == 1) { body((source as TSource[])[0]); return; } } else if (source is ICollection <TSource> ) { int elementsCount = (source as ICollection <TSource>).Count; if (elementsCount == 0) { return; } if (elementsCount == 1) { body((source as ICollection <TSource>).First()); return; } } if (ParallelizationProviderRegistry.Enabled && (string.IsNullOrEmpty(parallelizationPointName) || ParralelizationPointEnabled(parallelizationPointName))) { EnsureHttpContextItemsCollectionIsThreadSafe(); using (Profiler.Measure(GetPerformanceMeasureTitle(parallelizationPointName))) { ThreadDataManagerData parentData = ThreadDataManager.Current; var threadWrapper = new ThreadWrapper <TSource>(body, parentData); PromoteThreadAbortException(() => { Parallel.ForEach(source, threadWrapper.WrapperAction); }); } } else { foreach (var s in source) { body(s); } } }
public void Start() { ICollection <ThreadPoolDelegate> handlers = null; Monitor.Enter(_syncLock); try { if (_hasBeenStarted) { throw new InvalidOperationException("Pool has already been started."); } _hasBeenStarted = true; /* * Check to see if there were already items posted to the queue * before Start was called. If so, reset their timestamps to * the current time. */ if (_requestQueue.Count > 0) { ResetWorkRequestTimes(); } for (int n = 0; n < _initialThreadCount; n++) { ThreadWrapper thread = new ThreadWrapper(this, true, _threadPriority, string.Format("{0} (static)", _threadPoolName)); thread.Start(); } if (Started != null) { Delegate[] delegates = Started.GetInvocationList(); handlers = new List <ThreadPoolDelegate>(delegates.Length); foreach (ThreadPoolDelegate handler in delegates) { if (handler != null) { handlers.Add(handler); } } } } finally { Monitor.Exit(_syncLock); } if (handlers != null) { foreach (ThreadPoolDelegate handler in handlers) { handler(); } } }
public async Task <List <ThreadWrapper> > GetAllThreads() { try { _logger.LogInformation("Returning All Threads Lists"); var bsonList = await _threadRepo.GetAllThreads(); var jsonList = new List <Threads>(); var jsonThList = new List <ThreadWrapper>(); if (bsonList.Count == 0) { var list = new List <ThreadWrapper>(); list.Add(await AddThreads()); return(list); } for (int i = 0; i < bsonList.Count; i++) { if (await ThreadExists(bsonList[i].Id)) { TimeSpan ts = DateTime.Now.ToLocalTime() - bsonList[i].UpdatedOn.ToLocalTime(); if (ts.TotalMinutes < 5 || bsonList != null) { var json = new Threads(); var th = new ThreadWrapper(); var epList = new List <EndProduct>(); for (int j = 0; j < 5; j++) { var ep = new EndProduct(); ep.Title = bsonList[i].ThreadsInBson[j].Title; ep.Comments = bsonList[i].ThreadsInBson[j].Comments; epList.Add(ep); } jsonThList.Add(th); th.Threads = epList; json.ThreadWrapper = th; jsonList.Add(json); } else { _logger.LogInformation("Updating Threads List"); var list = new List <ThreadWrapper>(); list.Add(await AddThreads()); return(list); } } } return(jsonThList); } catch (Exception e) { _logger.LogCritical("Failed To Get All Thread Lists And Update If Needed. {e}", e); throw; } }
public bool Execute(Action method, int milliseconds) { if (tw.IsIdle() == false) { tw.Stop(); tw = new ThreadWrapper(); } return tw.Execute(method, milliseconds); }
private void ChangeThreadMenuItem_Click(object sender, EventArgs e) { if (threadsGrid.SelectedItems.Count == 1) { GridEXRow row = threadsGrid.SelectedItems[0].GetRow(); ThreadWrapper thread = (ThreadWrapper)NuGenHelperFunctions.TaggedObjects[(String)row.Cells[1].Value + (String)row.Cells[2].Value]; ChangeCurrentThread(thread); } }
private void threadsGrid_CellDoubleClick(object sender, RowActionEventArgs e) { if (threadsGrid.CurrentRow != null) { GridEXRow row = threadsGrid.CurrentRow; ThreadWrapper thread = (ThreadWrapper)NuGenHelperFunctions.TaggedObjects[(String)row.Cells[1].Value + (String)row.Cells[2].Value]; ChangeCurrentThread(thread); } }
public void StartSync(UserInputData input) { // create source streams using var sourceStream = _streamFactory.CreateSourceFileStream(input.SourceFilePath); using var mmf = MemoryMappedFile.CreateFromFile((FileStream)sourceStream, null, 0, MemoryMappedFileAccess.Read, HandleInheritability.Inheritable, false); var portionSizes = new long[_settings.Cores]; portionSizes[0] = sourceStream.ReadInt64(); for (var i = 1; i < portionSizes.Length; i++) { sourceStream.Seek(portionSizes[i - 1], SeekOrigin.Current); portionSizes[i] = sourceStream.ReadInt64(); } var offsets = new long[_settings.Cores]; offsets[0] = sizeof(long); for (var i = 1; i < offsets.Length; i++) { offsets[i] = offsets[i - 1] + portionSizes[i - 1] + sizeof(long); } var threads = new ThreadWrapper[_settings.Cores]; for (var i = 0; i < threads.Length; i++) { threads[i] = new ThreadWrapper(DecompressPortion); } for (var i = 0; i < _settings.Cores; i++) { var offset = offsets[i]; var size = portionSizes[i]; var view = mmf.CreateViewStream(offset, size, MemoryMappedFileAccess.Read); var zipStream = new GZipStream(view, CompressionMode.Decompress); threads[i].Start(new Tuple <Stream, int>(zipStream, i)); } using var targetStream = _streamFactory.CreateTargetFileStream(input.TargetFilePath); for (var i = 0; i < _settings.Cores; i++) { var thread = threads[i]; while (!thread.IsCompleted) { } using (var fs = File.OpenRead($"temp_decompress_{i}")) { fs.CopyTo(targetStream); } File.Delete($"temp_decompress_{i}"); } }
public SendingViewModel(Station.Neighbor neighbor, IEnumerable <SendFileModel> sendingFiles) { _neighbor = neighbor; _sendingFiles = sendingFiles.ToList(); _thread = new ThreadWrapper { DoWork = SendFiles, OnError = OnErrorWhileSendingFiles, OnExit = OnFinishSendingFiles }; }
public ReceivingViewModel(ReceivingSessionHandler.Session session, Station station) { _session = session; _station = station; _thread = new ThreadWrapper { DoWork = ReceiveFiles, OnError = OnErrorWhileReceivingFiles, OnExit = OnFinishReceivingFiles }; }
public Station(string name) { Name = name; _id = Guid.NewGuid().ToString(); _client = new UdpClient(); _thread = new ThreadWrapper { DoWork = ScanNeighbors }; _timer = new Timer(UpdateNeighborsStatus); }
private void lbCreated_DoubleClick(object sender, EventArgs e) { ThreadWrapper wrapper = lbCreated.SelectedItem as ThreadWrapper; wrapper.ChangeDisplayName += Wrapper_ChangeDisplayName; wrapper.StateRunning += Wrapper_StateRunning; wrapper.Start(); lbCreated.Items.Remove(wrapper); lbRunAndWait.Items.Add(wrapper); }
public void AddThread(string name, ThreadStart start, ThreadPriority priority) { ThreadWrapper @object = new ThreadWrapper(start, this); Thread thread = new Thread(@object.DoWork); thread.Priority = priority; thread.Name = name; RegisterThread(thread); thread.Start(); D.Sayf(1, "Started thread {0}", new object[] { name }); }
public void CheckWait() { /* * Show that wait works for letting the Thread finish initializaion. */ ThreadWrapper tw = new ThreadWrapper(); tw.StartThread(); Assert.False(tw.InitIsDone); tw.WaitForReady(); Assert.True(tw.InitIsDone); }
void SpawnThreads() { ThreadWrapper tw = new ThreadWrapper(); ParameterizedThreadStart ps = new ParameterizedThreadStart(ThreadWorker); tw.m_thread = new Thread(ps); tw.m_thread.Start(tw); }
private static void Faulted(ThreadWrapper wrapper) { _currentThreadCount--; }
private void GetThreadName(ThreadWrapper threadWrapper, ValueWrapper threadObject, NuGenFrameRefresher threadActiveFrameRefresher) { List<ModuleWrapper> modules = threadWrapper.FindModulesByName(GetThreadNameMethod.BaseTypeDefinition.ModuleScope.Assembly.FileName); if (modules.Count == 1) { ModuleWrapper module = modules[0]; FunctionWrapper getThreadNameFunction = module.GetFunction(GetThreadNameMethod.Token); List<ValueWrapper> arguments = new List<ValueWrapper>(1); arguments.Add(threadObject); NuGenEvaluationHandler methodCaller = new NuGenEvaluationHandler(threadActiveFrameRefresher); NuGenBaseEvaluationResult evaluationResult = methodCaller.CallFunction(getThreadNameFunction, arguments); if (evaluationResult.IsSuccessful) { if (evaluationResult.Result != null && (CorElementType)evaluationResult.Result.ElementType == CorElementType.ELEMENT_TYPE_STRING) { ValueWrapper dereferencedResult = evaluationResult.Result.DereferenceValue(); if (dereferencedResult != null) { EvaluatedThreadName = NuGenHelperFunctions.ShowEscapeCharacters(dereferencedResult.GetStringValue(), true); } } } } }
public void Start() { lock (this) { if (hasBeenStarted) { throw new InvalidOperationException("Pool has already been started."); } hasBeenStarted = true; // Check to see if there were already items posted to the queue // before Start was called. If so, reset their timestamps to // the current time. // if (requestQueue.Count > 0) { ResetWorkRequestTimes(); } for (int n = 0; n < initialThreadCount; n++) { ThreadWrapper thread = new ThreadWrapper(this, true, threadPriority, string.Format("{0} (static)", threadPoolName)); thread.Start(); } if (Started != null) { Started(); // TODO: reconsider firing this event while holding the lock... } } }
public ThreadedNotifier(Listener listener_0, Object notification_1) { this.listener = listener_0; this.notification = notification_1; aThread = new ThreadWrapper(this); aThread.Start(); }
private void ThreadProc() { bool done = false; while (!done) { WorkRequest wr = null; ThreadWrapper newThread = null; Monitor.Enter(_pool._syncLock); try { /* * As long as the request queue is empty and a shutdown hasn't * been initiated, wait for a new work request to arrive. */ bool timedOut = false; while (!_pool._stopInProgress && !timedOut && _pool._requestQueue.Count == 0) { if (!Monitor.Wait(_pool._syncLock, _permanent ? Timeout.Infinite : _pool._decayTime)) { /* * Timed out waiting for something to do. Only dynamically created * threads will get here, so bail out. */ timedOut = true; } } /* * We exited the loop above because one of the following conditions * was met: * - ThreadPool.Stop was called to initiate a shutdown. * - A dynamic thread timed out waiting for a work request to arrive. * - There are items in the work queue to process. * * If we exited the loop because there's work to be done, * a shutdown hasn't been initiated, and we aren't a dynamic thread * that timed out, pull the request off the queue and prepare to * process it. */ if (!_pool._stopInProgress && !timedOut && _pool._requestQueue.Count > 0) { wr = _pool._requestQueue.Dequeue(); /* * Check to see if this work request languished in the queue * very long. If it was in the queue >= the new thread trigger * time, and if we haven't reached the max thread count cap, * add a new thread to the pool. * * If the decision is made, create the new thread object (updating * the current # of threads in the pool), but defer starting the new * thread until the lock is released. */ TimeSpan requestTimeInQ = DateTime.Now.Subtract(wr.WorkingTime); if (requestTimeInQ >= _pool._newThreadTrigger && _pool._currentThreadCount < _pool._maxThreadCount) { /* * Note - the constructor for ThreadWrapper will update * pool.currentThreadCount. */ newThread = new ThreadWrapper(_pool, false, _priority, string.Format("{0} (dynamic)", _pool._threadPoolName)); /* * Since the current request we just dequeued is stale, * everything else behind it in the queue is also stale. * So reset the timestamps of the remaining pending work * requests so that we don't start creating threads * for every subsequent request. */ _pool.ResetWorkRequestTimes(); } } else { /* * Should only get here if this is a dynamic thread that * timed out waiting for a work request, or if the pool * is shutting down. */ _pool._currentThreadCount--; if (_pool._currentThreadCount == 0) { /* * Last one out turns off the lights. */ if (_pool.Stopped != null) { _pool.Stopped(); } _pool._stopCompleteEvent.Set(); } done = true; } } finally { Monitor.Exit(_pool._syncLock); } // No longer holding pool lock here... if (!done && wr != null) { /* * Check to see if this request has been cancelled while * stuck in the work queue. * * If the work request was pending, mark it processed and proceed * to handle. Otherwise, the request must have been cancelled * before we plucked it off the request queue. */ if (Interlocked.CompareExchange(ref wr.State, WorkRequest.PROCESSED, WorkRequest.PENDING) != WorkRequest.PENDING) { /* * Request was cancelled before we could get here. * Bail out. */ continue; } if (newThread != null) { newThread.Start(); } /* * Dispatch the work request. */ ThreadInfo originalThreadInfo = null; try { /* * Impersonate (as much as possible) what we know about * the thread that issued the work request. */ originalThreadInfo = ThreadInfo.Impersonate(wr.ThreadInfo); WorkRequestDelegate targetProc = wr.TargetProc as WorkRequestDelegate; if (targetProc != null) { targetProc(wr.ProcArg, wr.TimeStampStarted); } else { wr.TargetProc.DynamicInvoke(wr.ProcArgs); } } finally { /* * Restore our worker thread's identity. */ ThreadInfo.Restore(originalThreadInfo); } } } }
private void ChangeCurrentThread(ThreadWrapper thread) { NuGenUIHandler.Instance.ClearDebugPanels(true); NuGenUIHandler.Instance.ClearUserWarning(); NuGenUIHandler.Instance.ClearCodeDisplayers(true); NuGenDebugEventHandler.Instance.EventObjects.Thread = thread; NuGenDebugEventHandler.Instance.DisplayAllInformation(); }
private static void WorkDone(ThreadWrapper wrapper) { lock (__lockObject) { _availableThreads.Enqueue(wrapper); } _availableEventHandler.Set(); }
void ThreadProc() { Debug.WriteLine(string.Format("[{0}, {1}] Worker thread started", AppDomain.GetCurrentThreadId(), Thread.CurrentThread.Name)); bool done = false; while (!done) { WorkRequest wr = null; ThreadWrapper newThread = null; lock (pool) { // As long as the request queue is empty and a shutdown hasn't // been initiated, wait for a new work request to arrive. // bool timedOut = false; while (!pool.stopInProgress && !timedOut && (pool.requestQueue.Count == 0)) { if (!Monitor.Wait(pool, (isPermanent ? Timeout.Infinite : pool.decayTime))) { // Timed out waiting for something to do. Only dynamically created // threads will get here, so bail out. // timedOut = true; } } // We exited the loop above because one of the following conditions // was met: // - ThreadPool.Stop was called to initiate a shutdown. // - A dynamic thread timed out waiting for a work request to arrive. // - There are items in the work queue to process. // If we exited the loop because there's work to be done, // a shutdown hasn't been initiated, and we aren't a dynamic thread // that timed out, pull the request off the queue and prepare to // process it. // if (!pool.stopInProgress && !timedOut && (pool.requestQueue.Count > 0)) { wr = (WorkRequest)pool.requestQueue.Dequeue(); Debug.Assert(wr != null); // Check to see if this work request languished in the queue // very long. If it was in the queue >= the new thread trigger // time, and if we haven't reached the max thread count cap, // add a new thread to the pool. // // If the decision is made, create the new thread object (updating // the current # of threads in the pool), but defer starting the new // thread until the lock is released. // TimeSpan requestTimeInQ = DateTime.Now.Subtract(wr.workingTime); if ((requestTimeInQ >= pool.newThreadTrigger) && (pool.currentThreadCount < pool.maxThreadCount)) { // Note - the constructor for ThreadWrapper will update // pool.currentThreadCount. // newThread = new ThreadWrapper(pool, false, priority, string.Format("{0} (dynamic)", pool.threadPoolName)); // Since the current request we just dequeued is stale, // everything else behind it in the queue is also stale. // So reset the timestamps of the remaining pending work // requests so that we don't start creating threads // for every subsequent request. // pool.ResetWorkRequestTimes(); } } else { // Should only get here if this is a dynamic thread that // timed out waiting for a work request, or if the pool // is shutting down. // Debug.Assert((timedOut && !isPermanent) || pool.stopInProgress); pool.currentThreadCount--; if (pool.currentThreadCount == 0) { // Last one out turns off the lights. // Debug.Assert(pool.stopInProgress); if (pool.Stopped != null) { pool.Stopped(); } pool.stopCompleteEvent.Set(); } done = true; } } // lock // No longer holding pool lock here... if (!done && (wr != null)) { // Check to see if this request has been cancelled while // stuck in the work queue. // // If the work request was pending, mark it processed and proceed // to handle. Otherwise, the request must have been cancelled // before we plucked it off the request queue. // if (Interlocked.CompareExchange(ref wr.state, WorkRequest.PROCESSED, WorkRequest.PENDING) != WorkRequest.PENDING) { // Request was cancelled before we could get here. // Bail out. continue; } if (newThread != null) { Debug.WriteLine(string.Format("[{0}, {1}] Adding dynamic thread to pool", AppDomain.GetCurrentThreadId(), Thread.CurrentThread.Name)); newThread.Start(); } // Dispatch the work request. // ThreadInfo originalThreadInfo = null; try { // Impersonate (as much as possible) what we know about // the thread that issued the work request. // originalThreadInfo = ThreadInfo.Impersonate(wr.threadInfo); SharedCacheWorkRequestDelegate targetProc = wr.targetProc as SharedCacheWorkRequestDelegate; if (targetProc != null) { targetProc(wr.procArg, wr.timeStampStarted); } else { wr.targetProc.DynamicInvoke(wr.procArgs); } } catch (Exception e) { Debug.WriteLine(string.Format("Exception thrown performing callback:\n{0}\n{1}", e.Message, e.StackTrace)); } finally { // Restore our worker thread's identity. // ThreadInfo.Restore(originalThreadInfo); } } } Debug.WriteLine(string.Format("[{0}, {1}] Worker thread exiting pool", AppDomain.GetCurrentThreadId(), Thread.CurrentThread.Name)); }
public void Start() { ICollection<ThreadPoolDelegate> handlers = null; Monitor.Enter(_syncLock); try { if (_hasBeenStarted) { throw new InvalidOperationException("Pool has already been started."); } _hasBeenStarted = true; /* * Check to see if there were already items posted to the queue * before Start was called. If so, reset their timestamps to * the current time. */ if (_requestQueue.Count > 0) { ResetWorkRequestTimes(); } for (int n = 0; n < _initialThreadCount; n++) { ThreadWrapper thread = new ThreadWrapper(this, true, _threadPriority, string.Format("{0} (static)", _threadPoolName)); thread.Start(); } if (Started != null) { Delegate[] delegates = Started.GetInvocationList(); handlers = new List<ThreadPoolDelegate>(delegates.Length); foreach (ThreadPoolDelegate handler in delegates) { if (handler != null) handlers.Add(handler); } } } finally { Monitor.Exit(_syncLock); } if (handlers != null) { foreach (ThreadPoolDelegate handler in handlers) { handler(); } } }