zoukankan      html  css  js  c++  java
  • C#.NET Winform使用线程承载WCF (硬编码配置)

    winform同步承载WCF时,遇到大量请求,可能会阻塞UI线程。这时就需要开个线程来承载WCF。

    1.硬编码形式创建WCF服务,WCFServer类:

    using CommonUtils;
    using System;
    using System.Net;
    using System.ServiceModel;
    using System.ServiceModel.Description;
    using System.ServiceModel.Web;
    using System.Threading;
    
    namespace WcfYeah
    {
        public class WCFServer
        {
            public WebServiceHost host = null;
    
            /// <summary>
            /// 线程承载时sleep时间
            /// </summary>
            const int SleepTime = 100;
    
            private Thread _thread;
    
            /// <summary>
            /// WCF是否在运行
            /// </summary>
            private bool _isRunning;
    
            /// <summary>
            /// win server 2008以下用同步承载,以上用线程承载
            /// </summary>
            bool _useThreadHost = true;
    
            public WCFServer()
            {
                /* 硬编码形式配置WCF服务
                 * WebServiceHost需要在项目中右键引用System.ServiceModel.Web.dll程序集
                 *  */
    
                //对外连接数,根据实际情况加大
                if (ServicePointManager.DefaultConnectionLimit < 100)
                    System.Net.ServicePointManager.DefaultConnectionLimit = 100;
    
                string port = "16110";
    
                Uri baseURI = new Uri("http://localhost:" + port.ToString() + "/myapi");
                //注意:这里是实现类,不是接口,否则会报:ServiceHost 仅支持类服务类型。
                host = new WebServiceHost(typeof(Service1), baseURI);
    
                WebHttpBinding binding = new WebHttpBinding();
                // 这里不需要安全验证
                binding.Security.Mode = WebHttpSecurityMode.None;
                host.AddServiceEndpoint(typeof(IService1), binding, "");
                binding.MaxReceivedMessageSize = 2147483647;
                binding.MaxBufferSize = 2147483647;
                binding.MaxBufferPoolSize = 2147483647;
    
                binding.OpenTimeout = new TimeSpan(0, 10, 0);
                binding.CloseTimeout = new TimeSpan(0, 10, 0);
                binding.SendTimeout = new TimeSpan(0, 10, 0);
                binding.ReceiveTimeout = new TimeSpan(0, 10, 0);
    
                //项目需要引用System.Runtime.Serialization.dll
                binding.ReaderQuotas.MaxDepth = 2147483647;
                binding.ReaderQuotas.MaxStringContentLength = 2147483647;
                binding.ReaderQuotas.MaxArrayLength = 2147483647;
                binding.ReaderQuotas.MaxBytesPerRead = 2147483647;
                binding.ReaderQuotas.MaxNameTableCharCount = 2147483647;
    
                ServiceThrottlingBehavior mdBehavior = new ServiceThrottlingBehavior()
                {
                    MaxConcurrentCalls = 160,
                    MaxConcurrentInstances = 260,
                    MaxConcurrentSessions = 100
                };
                host.Description.Behaviors.Add(mdBehavior);
    
    
                #region 注册和初始化变量
                //注册
                _thread = new Thread(RunService);
    
                Version v2008 = new Version("6.0.0.0");
                Version osver = System.Environment.OSVersion.Version;
                GLog.WLog("当前系统版本是:" + osver.ToString());
                if (osver.CompareTo(v2008) >= 0)
                {
                    _useThreadHost = true;
                    GLog.WLog("系统是2008或以上");
                }
                else
                {
                    _useThreadHost = false;
                    GLog.WLog("系统是2008以下");
                }
                #endregion
    
            }
    
    
            public void Start()
            {
                if (_useThreadHost)
                {
                    GLog.WLog("Start() 线程承载,_isRunning:" + _isRunning);
                    if (!_isRunning)
                    {
                        GLog.WLog("Start() _thread.Start()");
                        _thread.Start();
                    }
                }
                else
                {
                    #region 同步承载
                    GLog.WLog("Start() 同步承载 ");
                    try
                    {
                        host.Open();
                    }
                    catch (Exception ex)
                    {                    
                        GLog.WLog("服务启动失败:" + ex.Message);
                        throw ex;
                    }
                    #endregion
                }
            }
    
            public void Close()
            {
                GLog.WLog("wcfservice Close");
                if (_useThreadHost)
                {
                    GLog.WLog("wcfservice Close 线程上停止WCF");
                    lock (this)
                    {
                        _isRunning = false;
                    }
                }
                else
                {
                    #region 同步
                    GLog.WLog("wcfservice Close 同步停止WCF");
                    try
                    {
                        if (host != null)
                        {
                            host.Close();
                        }
                        host = null;
                    }
                    catch (Exception ex)
                    {
                        GLog.WLog("wcfservice Close host.Close();时异常:" + ex.Message);
                    }
                    #endregion
                }
            }
    
            /// <summary>
            /// 线程承载WCF
            /// </summary>
            void RunService()
            {
                try
                {
                    _isRunning = true;
    
                    host.Open();
                    GLog.WLog("RunService host.Open();");
                    while (_isRunning)
                    {
                        Thread.Sleep(SleepTime);
                    }
                    host.Close();
                    GLog.WLog("RunService host.Close();");
                    ((IDisposable)host).Dispose();
                    GLog.WLog("RunService host Dispose;");
                }
                catch (Exception ex)
                {
                    GLog.WLog("RunService 异常;" + ex.Message);
    
                    try
                    {
                        if (host != null)
                            host.Close();
                    }
                    catch (Exception exClose)
                    {
                        GLog.WLog("host.Close();异常" + exClose.Message);
                    }
                }
            }
    
    
        }
    }

    GLog类:

    using System;
    using System.IO;
    
    namespace CommonUtils
    {
    
        public static class GLog
        {
            static object _lockObj = new object();
    
            public static void WLog(string content)
            {
                lock (_lockObj)
                {
                    string curPath = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().ManifestModule.FullyQualifiedName);
                    string logDir = "Logs";
                    string logDirFullName = Path.Combine(curPath, logDir);
    
                    try
                    {
                        if (!Directory.Exists(logDirFullName))
                            Directory.CreateDirectory(logDirFullName);
                    }
                    catch { return; }
    
                    string fileName = "Logs" + DateTime.Now.ToString("yyyy-MM-dd") + ".txt";
                    string logFullName = Path.Combine(logDirFullName, fileName);
    
                    try
                    {
                        using (FileStream fs = new FileStream(logFullName, FileMode.Append, FileAccess.Write))
                        using (StreamWriter sw = new StreamWriter(fs))
                            sw.WriteLine(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff") + " " + content);
                    }
                    catch { return; }
    
                }
            }
        }
    }

    IService1:

    using System.Runtime.Serialization;
    using System.ServiceModel;
    using System.ServiceModel.Web;
    
    namespace WcfYeah
    {
        // 注意: 使用“重构”菜单上的“重命名”命令,可以同时更改代码和配置文件中的接口名“IService1”。
        [ServiceContract]
        public interface IService1
        {        
            [OperationContract]
            [WebInvoke(ResponseFormat = WebMessageFormat.Json, RequestFormat = WebMessageFormat.Json)]
            CompositeType geta(CompositeType composite);
        }
    
        // 使用下面示例中说明的数据约定将复合类型添加到服务操作。
        // 可以将 XSD 文件添加到项目中。在生成项目后,可以通过命名空间“WcfYeah.ContractType”直接使用其中定义的数据类型。
        [DataContract]
        public class CompositeType
        {
            bool boolValue = true;
            string stringValue = "Hello ";
    
            [DataMember]
            public bool BoolValue
            {
                get { return boolValue; }
                set { boolValue = value; }
            }
    
            [DataMember]
            public string StringValue
            {
                get { return stringValue; }
                set { stringValue = value; }
            }
        }
    }

    Service1:

    using System;
    using System.ServiceModel;
    
    namespace WcfYeah
    {
        // 调整 ServiceBehavior,使其支持并发
        [ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.PerCall, UseSynchronizationContext = false)]
        public class Service1 : IService1
        {
            public CompositeType geta(CompositeType composite)
            {
                CompositeType myret = new CompositeType();
                try
                {
                    if(composite==null)
                        myret.StringValue = "输入实体为空:" + DateTime.Now.ToString();
                    else
                        myret.StringValue = "输入实体不为空:" + DateTime.Now.ToString();
                }
                catch (Exception ex)
                {
                    myret.StringValue = "发生异常:" + ex.Message;                 
                }
                return myret;
            }
    
        }
    }

    2.管理员权限启动这个WINFORM程序:

    using System;
    using System.Windows.Forms;
    using WcfYeah;
    
    namespace WindowsForms承载WCF
    {
        public partial class Form1 : Form
        {
            WCFServer wcfs = null;
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                try
                {
                    wcfs = new WCFServer();
                    wcfs.Start();
                    lblTip.Text = "服务已运行";
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
    
            private void Form1_FormClosing(object sender, FormClosingEventArgs e)
            {
                try
                {
                    if (wcfs != null)
                    {
                        wcfs.Close();
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message);
                }
            }
        }
    }

    -

  • 相关阅读:
    AES加解密
    redis HyperLogLog使用
    vi常用操作
    redis string使用
    用jdk命令定位java应用问题
    用户态、内核态及零拷贝
    缓存穿透与雪崩
    ReentrantLock、Semaphore、AQS
    redis list使用
    不同数据库取并集、交集、差集
  • 原文地址:https://www.cnblogs.com/runliuv/p/15623141.html
Copyright © 2011-2022 走看看