代码之家  ›  专栏  ›  技术社区  ›  Nate Pinchot

在调用期间在WCF服务中创建后台线程会占用ASP.NET线程池中的线程吗?

  •  4
  • Nate Pinchot  · 技术社区  · 16 年前

    以下代码是WCF服务的一部分。即使将eventwatcher设置为isbackground=true,它是否会占用ASP.NET线程池中的线程?

    /// <summary>
    /// Provides methods to work with the PhoneSystem web services SDK.
    /// This is a singleton since we need to keep track of what lines (extensions) are open.
    /// </summary>
    public sealed class PhoneSystemWebServiceFactory : IDisposable
    {
        // singleton instance reference
        private static readonly PhoneSystemWebServiceFactory instance = new PhoneSystemWebServiceFactory();
        private static readonly object l = new object();
        private static volatile Hashtable monitoredExtensions = new Hashtable();
        private static readonly PhoneSystemWebServiceClient webServiceClient = CreateWebServiceClient();
        private static volatile bool isClientRegistered;
        private static volatile string clientHandle;
        private static readonly Thread eventWatcherThread = new Thread(EventPoller) {IsBackground = true};
    
        #region Constructor
        // these constructors are hacks to make the C# compiler not mark beforefieldinit
        //  more info: http://www.yoda.arachsys.com/csharp/singleton.html
        static PhoneSystemWebServiceFactory()
        {
        }
    
        PhoneSystemWebServiceFactory()
        {
        }
        #endregion
    
        #region Properties
        /// <summary>
        /// Gets a thread safe instance of PhoneSystemWebServiceFactory
        /// </summary>
        public static PhoneSystemWebServiceFactory Instance
        {
            get { return instance; }
        }
        #endregion
    
        #region Private methods
        /// <summary>
        /// Create and configure a PhoneSystemWebServiceClient with basic http binding and endpoint from app settings.
        /// </summary>
        /// <returns>PhoneSystemWebServiceClient</returns>
        private static PhoneSystemWebServiceClient CreateWebServiceClient()
        {
            string url = ConfigurationManager.AppSettings["PhoneSystemWebService_Url"];
            if (string.IsNullOrEmpty(url))
            {
                throw new ConfigurationErrorsException(
                    "The AppSetting \"PhoneSystemWebService_Url\" could not be found. Check the application configuration and ensure that the element exists. Example: <appSettings><add key=\"PhoneSystemWebService_Url\" value=\"http://xyz\" /></appSettings>");
            }
    
            return new PhoneSystemWebServiceClient(new BasicHttpBinding(), new EndpointAddress(url));
        }
        #endregion
    
        #region Event poller
        public static void EventPoller()
        {
            while (true)
            {
                if (Thread.CurrentThread.ThreadState == ThreadState.Aborted ||
                    Thread.CurrentThread.ThreadState == ThreadState.AbortRequested ||
                    Thread.CurrentThread.ThreadState == ThreadState.Stopped ||
                    Thread.CurrentThread.ThreadState == ThreadState.StopRequested)
                    break;
    
                // get events
                //webServiceClient.GetEvents(clientHandle, 30, 100);
            }
    
            Thread.Sleep(5000);
        }
        #endregion
    
        #region Client registration methods
        private static void RegisterClientIfNeeded()
        {
            if (isClientRegistered)
            {
                return;
            }
    
            lock (l)
            {
                // double lock check
                if (isClientRegistered)
                {
                    return;
                }
    
                //clientHandle = webServiceClient.RegisterClient("PhoneSystemWebServiceFactoryInternal", null);
                isClientRegistered = true;
            }
        }
    
        private static void  UnregisterClient()
        {
            if (!isClientRegistered)
            {
                return;
            }
    
            lock (l)
            {
                // double lock check
                if (!isClientRegistered)
                {
                    return;
                }
    
                //webServiceClient.UnegisterClient(clientHandle);
            }
        }
        #endregion
    
        #region Phone extension methods
        public bool SubscribeToEventsForExtension(string extension)
        {
            if (monitoredExtensions.Contains(extension))
            {
                return false;
            }
    
            lock (monitoredExtensions.SyncRoot)
            {
                // double lock check
                if (monitoredExtensions.Contains(extension))
                {
                    return false;
                }
    
                RegisterClientIfNeeded();
    
                // open line so we receive events for extension
                LineInfo lineInfo;
                try
                {
                    //lineInfo = webServiceClient.OpenLine(clientHandle, extension);
                }
                catch (FaultException<PhoneSystemWebSDKErrorDetail>)
                {
                    // TODO: log error
                    return false;
                }
    
                // add extension to list of monitored extensions
                //monitoredExtensions.Add(extension, lineInfo.lineID);
                monitoredExtensions.Add(extension, 1);
    
                // start event poller thread if not already started
                if (eventWatcherThread.ThreadState == ThreadState.Stopped || eventWatcherThread.ThreadState == ThreadState.Unstarted)
                {
                    eventWatcherThread.Start();
                }
    
                return true;
            }
        }
    
        public bool UnsubscribeFromEventsForExtension(string extension)
        {
            if (!monitoredExtensions.Contains(extension))
            {
                return false;
            }
    
            lock (monitoredExtensions.SyncRoot)
            {
                if (!monitoredExtensions.Contains(extension))
                {
                    return false;
                }
    
                // close line
                try
                {
                    //webServiceClient.CloseLine(clientHandle, (int) monitoredExtensions[extension]);
                }
                catch (FaultException<PhoneSystemWebSDKErrorDetail>)
                {
                    // TODO: log error
                    return false;
                }
    
                // remove extension from list of monitored extensions
                monitoredExtensions.Remove(extension);
    
                // if we are not monitoring anything else, stop the poller and unregister the client
                if (monitoredExtensions.Count == 0)
                {
                    eventWatcherThread.Abort();
                    UnregisterClient();
                }
    
                return true;
            }
        }
    
        public bool IsExtensionMonitored(string extension)
        {
            lock (monitoredExtensions.SyncRoot)
            {
                return monitoredExtensions.Contains(extension);
            }
        }
        #endregion
    
        #region Dispose
        public void Dispose()
        {
            lock (l)
            {
                // close any open lines
                var extensions = monitoredExtensions.Keys.Cast<string>().ToList();
    
                while (extensions.Count > 0)
                {
                    UnsubscribeFromEventsForExtension(extensions[0]);
                    extensions.RemoveAt(0);
                }
    
                if (!isClientRegistered)
                {
                    return;
                }
    
                // unregister web service client
                UnregisterClient();
            }
        }
        #endregion
    }
    
    1 回复  |  直到 16 年前
        1
  •  4
  •   SLaks    16 年前

    不。

    使用创建的线程 new Thread(...) (而不是 ThreadPool.QueueUserWorkItem )与线程工具无关,不管 IsBackground .

    推荐文章