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. 加入自定义块对fashion_mnist数据集进行softmax分类

    在之前,我们实现了使用torch自带的层对fashion_mnist数据集进行分类.这次,我们加入一个自己实现的block,实现一个四层的多层感知机进行softmax分类,作为对"自定义块& ...

  2. Docker 安装,常用命令

    安装Docker 官方所有操作系统安装教程:Install Docker Engine on CentOS | Docker Documentation,其中CentOS安装docker引擎的代码: ...

  3. SemanticFunction 融合 LLM 和传统编程

    本文将继续和大家介绍 SemanticKernel 神奇的魔法,将使用 LLM 大语言模型编写的自然语言函数和传统的编程语言编写的函数融合到一起的例子.通过本文的例子,大家可以看到 SemanticK ...

  4. Unity3D OpenVR 虚拟现实 保龄球打砖块游戏开发

    据说水哥买了 Valve Index 设备,既然这个设备这么贵,不开发点有(zhi)趣(zhang)游戏就感觉对不起这个设备.本文将来开始着手开发一个可玩性不大,观赏性极强的保龄球打砖块游戏.这仅仅只 ...

  5. 局域网内一部分网络设备无法ping通,icmp_seq=1 目标主机不可达

    问题: 来自 192.168.2.99 icmp_seq=1 目标主机不可达.   最近想在局域网内搭建一台服务器,打开SSH服务后发现局域网内的一部分设备无法使用,尝试了各种办法都没能解决,重装系统 ...

  6. 21°C的冬天

    2023-12-08 16:15:36 星期五 标题没有在胡说,今天穿着初秋的衣服还嫌热,尤其是蒋震图书馆的空调更是燥热. 明天就去考教资面试了,但是一点也没有学习的兴趣,今天下午四点就写完了这周所有 ...

  7. SQL Server实战五:存储过程与触发器

      本文介绍基于Microsoft SQL Server软件,实现数据库存储过程与触发器的创建.执行.修改与删除等操作. 目录 1 交互式创建并执行--存储过程一 2 交互式创建并执行--存储过程二 ...

  8. 07. rails 创建user模型

    rails帮助命令 rails -h 创建user模型 命令行 haima@haima-PC:/media/haima/34E401CC64DD0E28/site/go/src/ruby/circle ...

  9. NSThread的start方法内部做了什么?

    下面是NSThread start方法的汇编码: 1 1 1 ;Foundation`-[NSThread start]: 2 2 2 -> 0x7fff2594f47f <+0>: ...

  10. ansible系列(30)--ansible的role详解

    目录 1. Ansible Roles 1.1 roles目录结构 1.2 roles编写步骤 1.2.1 编写基本的roles 1.2.2 roles的调用 1.2.3 roles中使用变量 1.2 ...