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);
}
}
}
}

-

C#.NET Winform使用线程承载WCF (硬编码配置)的更多相关文章

  1. C#.NET 操作Windows服务承载WCF

    Windows服务的制作.安装可以参考这篇: C#.NET 操作Windows服务(安装.卸载) - runliuv - 博客园 (cnblogs.com) 本篇会在这个解决方案基础上,继续修改. 一 ...

  2. [WinForm]WinForm跨线程UI操作常用控件类大全

    前言 在C#开发的WinForm窗体程序开发的时候,经常会使用多线程处理一些比较耗时之类的操作.不过会有一个问题:就是涉及到跨线程操作UI元素. 相信才开始接触的人一定会遇上这个问题. 为了解决这个问 ...

  3. Wcf for wp8 使用iis Express 承载Wcf服务部署发布网站(三)

    我们接下来要做的是 本地电脑当作服务器(模拟外网服务器)来承载Wcf服务程序,通过引用本地电脑ip地址访问wcf服务程序接口 http://192.168.1.123/Service1.svc 一.先 ...

  4. WCF中常见的几种Host,承载WCF服务的方法

    1:写在前面 我们都知道WCF在运行的时候必须自己提供宿主来承载服务.WCF 本身没有附带宿主,而是提供了一个 ServiceHost 的类,该类允许您在自己的应用程序中host WCF 服务.然后调 ...

  5. WCF学习笔记(2)——使用IIS承载WCF服务

    通过前面的笔记我们知道WCF服务是不能独立存在,必须“寄宿”于其他的应用程序中,承载WCF服务的应用程序我们称之为“宿主”.WCF的多种可选宿主,其中比较常见的就是承载于IIS服务中,在这里我们来学习 ...

  6. 如何在IIS中承载WCF NetTcpBinding 服务

    这篇博客将介绍如何在IIS中承载NetTcpBinding的服务. 1. 首先准备服务代码. Contract namespace Contract { [ServiceContract] publi ...

  7. 编写高质量代码改善C#程序的157个建议——建议87:区分WPF和WinForm的线程模型

    建议87:区分WPF和WinForm的线程模型 WPF和WinForm窗体应用程序都有一个要求,那就是UI元素(如Button.TextBox等)必须由创建它的那个线程进行更新.WinForm在这方面 ...

  8. 使用IIS承载WCF服务

    作者:jiankunking 出处:http://blog.csdn.net/jiankunking 1.WCF能够方便的通过IIS承载,此承载模型与ASP.NET和ASP.NET Web Servi ...

  9. 【流媒体】 Android 实时视频编码—H.264硬编码

    [流媒體] Android 实时视频编码—H.264硬编码 SkySeraph Apr 4th 2012 Email:skyseraph00@163.com 1  硬编码 & 软编码 硬编码: ...

  10. [老老实实学WCF] 第二篇 配置WCF

    老老实实学WCF 第二篇 配置WCF 在上一篇中,我们在一个控制台应用程序中编写了一个简单的WCF服务并承载了它.先回顾一下服务端的代码: using System; using System.Col ...

随机推荐

  1. Flink 如何实时分析 Iceberg 数据湖的 CDC 数据

    简介: 数据湖的架构中,CDC 数据实时读写的方案和原理 本文由李劲松.胡争分享,社区志愿者杨伟海.李培殿整理.主要介绍在数据湖的架构中,CDC 数据实时读写的方案和原理.文章主要分为 4 个部分内容 ...

  2. Dubbo-go v3.0 正式发布 ——打造国内一流开源 Go 服务框架

    ​简介:Dubbo-go 是常新的,每年都在不断进化.介绍 Dubbo-go 3.0 工作之前,先回顾其过往 6 年的发展历程,以明晰未来的方向. ​ 作者 | 李志信 来源 | 阿里技术公众号 作者 ...

  3. K8s包管理工具Helm v3(19)

    一.Helm概述 官网:https://v3.helm.sh/zh/docs/ https://helm.sh/ helm 官方的 chart 站点: https://hub.kubeapps.com ...

  4. LabView十六进制与字符串之间的转换

    一.准备工具 Labview开发软件 字符串与十六进制的转换工具(做测试使用) 在线转换工具:IEE754浮点数16进制转换 本地工具如下图所示: 二.LabView字符串转换为十六进制 在数值中选择 ...

  5. Docker部署Scrapy-redis分布式爬虫框架(整合Selenium+Headless Chrome网页渲染)

    前言 我的京东价格监控网站需要不间断爬取京东商品页面,爬虫模块我采用了Scrapy+selenium+Headless Chrome的方式进行商品信息的采集. 由于最近爬虫用的服务器到期,需要换到新服 ...

  6. Python使用HTMLTestRunner运行所有用例并产生报告

    #coding:utf-8import unittestimport osimport sysimport HTMLTestRunnercase_path = os.path.join(os.path ...

  7. 11、操作系统安全加固-Windows 加固

    1.账号管理与认证授权 1.1.按用户类型分配账号 目的:根据系统要求,设定不同账户和组,管理员.数据库sa.审计用户.来宾用户等 实施方法: 打开本地用户和计算机管理器 或 打开运行,输入 lusr ...

  8. github无法push?看这篇文章就够了

    参考文章: https://mp.weixin.qq.com/s/56Dp3pM0BMyH2GZMGEsmCQ

  9. golang计时器

    timer 计时器 用于在指定的Duration类型时间后调用函数或计算表达式. 如果只是想指定时间之后执行,使用time.Sleep() 使用NewTimer(),可以返回的Timer类型在计时器到 ...

  10. ansible(8)--ansible的hostname模块

    1. hostname模块 功能:管理远程主机的主机名. 示例一:更改192.168.20.22的主机名为nginx01: [root@xuzhichao ~]# ansible 192.168.20 ...