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. 剑指offer66(Java)-构建乘积数组(中等)

    题目: 给定一个数组 A[0,1,-,n-1],请构建一个数组 B[0,1,-,n-1],其中 B[i] 的值是数组 A 中除了下标 i 以外的元素的积, 即 B[i]=A[0]×A[1]×-×A[i ...

  2. 力扣68(java)-文本左右对齐(困难)

    题目: 给定一个单词数组 words 和一个长度 maxWidth ,重新排版单词,使其成为每行恰好有 maxWidth 个字符,且左右两端对齐的文本. 你应该使用 "贪心算法" ...

  3. 模拟IDC spark读写MaxCompute实践

    简介: 现有湖仓一体架构是以 MaxCompute 为中心读写 Hadoop 集群数据,有些线下 IDC 场景,客户不愿意对公网暴露集群内部信息,需要从 Hadoop 集群发起访问云上的数据.本文以 ...

  4. Elasticsearch生态&技术峰会 | 阿里云Elasticsearch云原生内核

    简介: 开源最大的特征就是开放性,云生态则让开源技术更具开放性与创造性,Elastic 与阿里云的合作正是开源与云生态共生共荣的典范.值此合作三周年之际,我们邀请业界资深人士相聚云端,共话云上Elas ...

  5. 阿里巴巴超大规模 Kubernetes 基础设施运维体系揭秘

    ​简介:ASI 作为阿里集团.阿里云基础设施底座,为越来越多的云产品提供更多专业服务,托管底层 K8s 集群,屏蔽复杂的 K8s 门槛.透明几乎所有的基础设施复杂度,并用专业的产品技术能力兜底稳定性, ...

  6. [Py] Python json str 字符串转为对象 (字典)

    import json json = '{"code": 0}' # Deserialize ``s`` (a ``str``, ``bytes`` or ``bytearray` ...

  7. dotnet 6 精细控制 HttpClient 网络请求超时

    本文告诉大家如何在 dotnet 6 下使用 HttpClient 更加精细的控制网络请求的超时,实现 HttpWebRequest 的 ReadWriteTimeout 功能 本文将介绍如何在 Ht ...

  8. 迁移 dotnet 6 提示必须将目标平台设置为 Windows 平台

    我在迁移一个古老的项目为 .NET 6 框架,但是 VS 提示 error NETSDK1136 如果使用 Windows 窗体或 WPF,或者引用使用 Windows 窗体或 WPF 的项目或包,则 ...

  9. vim 使用clang-format 格化C/C++/Java/JavaScript

    vim 使用clang-format 格化C/C++/Java/JavaScript 参考信息 官方参考https://clang.llvm.org/docs/ClangFormat.html 安装 ...

  10. C#的基于.net framework的Winform编程 - 编程手把手系列文章

    对于C#,笔者最早接触的是ASP.NET里的开发,后面对Winform程序也有一定的开发,但是真正理解和重新编码是这些年的事,在我的C#标签里有一些例子,记录了winform程序开发的一些功能.此文只 ...