private void SetDateHeaderHelper(string headerName, DateTime dateTime) { #if DEBUG using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) { #endif if (dateTime == DateTime.MinValue) { SetSpecialHeaders(headerName, null); // remove header } else { SetSpecialHeaders(headerName, DateToString(dateTime)); } #if DEBUG } #endif }
private DateTime GetDateHeaderHelper(string headerName) { #if DEBUG using (DebugThreadTracking.SetThreadKind(ThreadKinds.User | ThreadKinds.Async)) { #endif string headerValue = _webHeaderCollection[headerName]; if (headerValue == null) { return(DateTime.MinValue); // MinValue means header is not present } return(StringToDate(headerValue)); #if DEBUG } #endif }
protected HttpWebRequest(SerializationInfo serializationInfo, StreamingContext streamingContext) : base(serializationInfo, streamingContext) { #if DEBUG using (DebugThreadTracking.SetThreadKind(ThreadKinds.User)) { #endif _webHeaderCollection = (WebHeaderCollection)serializationInfo.GetValue("_HttpRequestHeaders", typeof(WebHeaderCollection)); Proxy = (IWebProxy)serializationInfo.GetValue("_Proxy", typeof(IWebProxy)); KeepAlive = serializationInfo.GetBoolean("_KeepAlive"); Pipelined = serializationInfo.GetBoolean("_Pipelined"); AllowAutoRedirect = serializationInfo.GetBoolean("_AllowAutoRedirect"); if (!serializationInfo.GetBoolean("_AllowWriteStreamBuffering")) { _Booleans &= ~Booleans.AllowWriteStreamBuffering; } _maximumAllowedRedirections = serializationInfo.GetInt32("_MaximumAllowedRedirections"); AllowAutoRedirect = serializationInfo.GetInt32("_AutoRedirects") > 0; Timeout = serializationInfo.GetInt32("_Timeout"); try { ReadWriteTimeout = serializationInfo.GetInt32("_ReadWriteTimeout"); } catch { // default } try { MaximumResponseHeadersLength = serializationInfo.GetInt32("_MaximumResponseHeadersLength"); } catch { // default } ContentLength = serializationInfo.GetInt64("_ContentLength"); MediaType = serializationInfo.GetString("_MediaType"); _originVerb = serializationInfo.GetString("_OriginVerb"); ConnectionGroupName = serializationInfo.GetString("_ConnectionGroupName"); ProtocolVersion = (Version)serializationInfo.GetValue("_Version", typeof(Version)); _requestUri = (Uri)serializationInfo.GetValue("_OriginUri", typeof(Uri)); #if DEBUG } #endif }
/// <summary> /// <para>Thread for the timer. Ignores all exceptions. If no activity occurs for a while, /// the thread will shut down.</para> /// </summary> private static void ThreadProc() { if (NetEventSource.IsEnabled) { NetEventSource.Enter(null); } #if DEBUG DebugThreadTracking.SetThreadSource(ThreadKinds.Timer); using (DebugThreadTracking.SetThreadKind(ThreadKinds.System | ThreadKinds.Async)) { #endif // Set this thread as a background thread. On AppDomain/Process shutdown, the thread will just be killed. Thread.CurrentThread.IsBackground = true; // Keep a permanent lock on s_Queues. This lets for example Shutdown() know when this thread isn't running. lock (s_Queues) { // If shutdown was recently called, abort here. if (Interlocked.CompareExchange(ref s_ThreadState, (int)TimerThreadState.Running, (int)TimerThreadState.Running) != (int)TimerThreadState.Running) { return; } bool running = true; while (running) { try { s_ThreadReadyEvent.Reset(); while (true) { // Copy all the new queues to the real queues. Since only this thread modifies the real queues, it doesn't have to lock it. if (s_NewQueues.Count > 0) { lock (s_NewQueues) { for (LinkedListNode <WeakReference> node = s_NewQueues.First; node != null; node = s_NewQueues.First) { s_NewQueues.Remove(node); s_Queues.AddLast(node); } } } int now = Environment.TickCount; int nextTick = 0; bool haveNextTick = false; for (LinkedListNode <WeakReference> node = s_Queues.First; node != null; /* node = node.Next must be done in the body */) { TimerQueue queue = (TimerQueue)node.Value.Target; if (queue == null) { LinkedListNode <WeakReference> next = node.Next; s_Queues.Remove(node); node = next; continue; } // Fire() will always return values that should be interpreted as later than 'now' (that is, even if 'now' is // returned, it is 0x100000000 milliseconds in the future). There's also a chance that Fire() will return a value // intended as > 0x100000000 milliseconds from 'now'. Either case will just cause an extra scan through the timers. int nextTickInstance; if (queue.Fire(out nextTickInstance) && (!haveNextTick || IsTickBetween(now, nextTick, nextTickInstance))) { nextTick = nextTickInstance; haveNextTick = true; } node = node.Next; } // Figure out how long to wait, taking into account how long the loop took. // Add 15 ms to compensate for poor TickCount resolution (want to guarantee a firing). int newNow = Environment.TickCount; int waitDuration = haveNextTick ? (int)(IsTickBetween(now, nextTick, newNow) ? Math.Min(unchecked ((uint)(nextTick - newNow)), (uint)(Int32.MaxValue - c_TickCountResolution)) + c_TickCountResolution : 0) : c_ThreadIdleTimeoutMilliseconds; if (NetEventSource.IsEnabled) { NetEventSource.Info(null, $"Waiting for {waitDuration}ms"); } int waitResult = WaitHandle.WaitAny(s_ThreadEvents, waitDuration, false); // 0 is s_ThreadShutdownEvent - die. if (waitResult == 0) { if (NetEventSource.IsEnabled) { NetEventSource.Info(null, "Awoke, cause: Shutdown"); } running = false; break; } if (NetEventSource.IsEnabled) { NetEventSource.Info(null, $"Awoke, cause {(waitResult == WaitHandle.WaitTimeout ? "Timeout" : "Prod")}"); } // If we timed out with nothing to do, shut down. if (waitResult == WaitHandle.WaitTimeout && !haveNextTick) { Interlocked.CompareExchange(ref s_ThreadState, (int)TimerThreadState.Idle, (int)TimerThreadState.Running); // There could have been one more prod between the wait and the exchange. Check, and abort if necessary. if (s_ThreadReadyEvent.WaitOne(0, false)) { if (Interlocked.CompareExchange(ref s_ThreadState, (int)TimerThreadState.Running, (int)TimerThreadState.Idle) == (int)TimerThreadState.Idle) { continue; } } running = false; break; } } } catch (Exception exception) { if (ExceptionCheck.IsFatal(exception)) { throw; } if (NetEventSource.IsEnabled) { NetEventSource.Error(null, exception); } // The only options are to continue processing and likely enter an error-loop, // shut down timers for this AppDomain, or shut down the AppDomain. Go with shutting // down the AppDomain in debug, and going into a loop in retail, but try to make the // loop somewhat slow. Note that in retail, this can only be triggered by OutOfMemory or StackOverflow, // or an exception thrown within TimerThread - the rest are caught in Fire(). #if !DEBUG Thread.Sleep(1000); #else throw; #endif } } } if (NetEventSource.IsEnabled) { NetEventSource.Info(null, "Stop"); } #if DEBUG } #endif }