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. 力扣442(java)-数组中重复的数据(中等)

    题目: 给你一个长度为 n 的整数数组 nums ,其中 nums 的所有整数都在范围 [1, n] 内,且每个整数出现 一次 或 两次 .请你找出所有出现 两次 的整数,并以数组形式返回. 你必须设 ...

  2. 关于CDN的原理、术语和应用场景那些事

    关于CDN,想必你一定看过很多官方的解释.今天,CDN百科第七期,将用一篇3844字的文章,来带你了解CDN的诞生.术语.原理.特征以及应用场景,看完这篇文章,相信你将会对CDN这项互联网基础设施有更 ...

  3. 基于Python语言的数据可视化工具

    在数据分析中常用的图表可以使用使用 python语言的 matplotlib 和 seaborn 库选择要显示的可视化对象. 一.Matplotlib Matplotlib 是一个 Python 的 ...

  4. [FAQ] Vmmem 内存占用高的问题 -Win10 -WLS2

    1按下Windows + R 键,输入 %UserProfile% 并运行进入用户文件夹 2新建文件 .wslconfig ,然后记事本编辑 3 填入以下内容并保存, memory为系统内存上限,这里 ...

  5. Prometheus+Grafana+alertmanager构建企业级监控系统(三)

    七.Prometheus监控扩展 7.1 Promethues 采集tomcat监控数据 tomcat_exporter地址:https://github.com/nlighten/tomcat_ex ...

  6. Partition和ReduceTask的关系

    先看源码: numPartitions = conf.getNumReduceTasks(); if (numPartitions > 1) { //设置了ReduceTask个数后(大于1), ...

  7. ITIL4中的关键概念

    1.价值和价值共创 什么是价值 通俗表达:这有啥用? 正式表达:这能带来什么益处或起什么作用? 反问式求证: 假如没有的话,会有什么后果? 具体情境提问:如果缺少IT运维人员,业务系统会面临怎样的状况 ...

  8. NumPy 数组创建方法与索引访问详解

    NumPy 创建数组 NumPy 中的核心数据结构是 ndarray,它代表多维数组.NumPy 提供了多种方法来创建 ndarray 对象,包括: 使用 array() 函数 array() 函数是 ...

  9. rails 上传文件

    控制器文件 app/controllers/api/v1/order_controller.rb def create # 从本地读取 log_dir = File.expand_path(File. ...

  10. ansible系列(34)--ansible实战之部署WEB集群架构(4)

    目录 1. 业务环境部署 1.1 wordpress-base编写 1.2 wordpress-web编写 1.3 wordpress-mysql编写 1.4 wordpress-proxy编写 1. ...