WCF 服务的集合管理器的设计
今天是2019年2月1日,时间过得针对,马上就年底了,当前新年也离我们越来越近了。在此,我也祝福经常浏览我博客的朋友们“新年快乐、阖家欢乐”,来年有一个好彩头。在即将结束这一年之计,写今年的最后一片文章。WCF 我相信大家都使用过,每次宿主该服务的时候都要使用 ServiceHost,如果要加载多个 WCF 服务,那就需要多次 ServiceHost 实例化,而且这个过程大致都是一样的,这就有点太麻烦了。正好现在有时间,也有项目的需要,我就写了一份 WCF 服务的集合管理器,可以加载多个 WCF 服务,也可以对 WCF 的服务进行开启或者关闭的操作,使用起来还是比较方便的。这个设计已经改过多次,现在这个版本是目前最合适、最稳定的版本。
说写就写,OO的三大基本原则,1、面向抽象编程,不要面向实现编程;2、多组合少继承;3、哪里有变化点就封装哪里。
这三大原则我们要死死的记在心里,融化进血液里,由此,我的做法是做接口的抽象设计,代码如下:
1、接口 IWcfServiceManager 的设计如下:
/// <summary>
/// WCF 服务的实例管理器,该类型可以实现对容器内部的 WCF 服务对象进行增加、删除、查询、开启和关闭的操作。
/// </summary>
public interface IWcfServiceManager:IDisposable
{
/// <summary>
/// 以指定的名称增加 WCF 服务实例,但是该服务并没有启动。
/// </summary>
/// <param name="serviceName">表示 WCF 服务的名称。</param>
/// <returns>返回布尔值,true 表示增加 WCF 服务成功,false 表示增加 WCF 失败。</returns>
bool AddService(string serviceName); /// <summary>
/// 从容器对象中删除指定名称的 WCF 服务实例。
/// </summary>
/// <param name="serviceName">表示 WCF 服务的名称。</param>
/// <returns>返回布尔值,true 表示删除 WCF 服务成功,false 表示删除 WCF 服务失败。</returns>
bool RemoveService(string serviceName); /// <summary>
/// 获取所有的 WCF 服务实例的集合。
/// </summary>
/// <returns>返回所有的 WCF 服务实例集合。</returns>
IEnumerable<WcfService> GetServices(); /// <summary>
/// 根据指定的名称获取 WCF 服务实例。
/// </summary>
/// <param name="serviceName">表示 WCF 服务的名称。</param>
/// <returns>返回和指定名称相匹配的 WCF 服务实例,如果不存在则会返回 Null 值。</returns>
WcfService GetService(string serviceName); /// <summary>
/// 开启指定名称 WCF 服务实例,此时该服务可以为客户端提供服务了。
/// </summary>
/// <param name="serviceName">表示 WCF 服务的名称。</param>
/// <returns>返回布尔值,true 表示成功开启 WCF 服务,false 表示开启式 WCF 服务失败。</returns>
bool Start(string serviceName); /// <summary>
/// 开启所有的 WCF 服务实例。
/// </summary>
void StartAll(); /// <summary>
/// 关闭指定名称的 WCF 服务实例,此时该服务就不能为客户端提供任何服务了。
/// </summary>
/// <param name="serviceName">表示 WCF 服务的名称。</param>
/// <returns>返回布尔值,true 表示成功关闭 WCF 服务实例,false 表示关闭 WCF 服务实例失败。</returns>
bool Close(string serviceName); /// <summary>
/// 关闭所有的 WCF 服务实例,停止所有的服务。
/// </summary>
void CloseAll(); /// <summary>
/// 根据指定的名称来判断该 WCF 服务实例是否已经开启。
/// </summary>
/// <param name="serviceName">表示 WCF 服务的名称。</param>
/// <returns>返回布尔值,true 表示该名称的 WCF 服务实例是已经开启的,false 表示该名称的 WCF 服务实例是未开启的。</returns>
bool IsStartup(string serviceName); /// <summary>
/// 获取 WCF 服务实例的个数
/// </summary>
int Count { get; }
}
这个接口的设计就不多说了,很简单,继续我们下一步。
2、实现接口类的设计,类名是:WcfServiceManager.cs
该类型都有详细的备注信息,不用我多说了。
/// <summary>
/// WCF 服务的实例管理器,该类型可以实现对容器内部的 WCF 服务对象进行增加、删除、查询、开启和关闭的操作。
/// </summary>
public abstract class WcfServiceManager : IWcfServiceManager, IDisposable
{
#region 私有字段 private ConcurrentDictionary<string, ServiceHost> _serviceHostGroup;
private ConcurrentDictionary<string, ServiceHost> _serviceHostTemp;
private string[] _assemblyNames;
private bool _disposed;//是否回收完毕
private IList<Assembly> _assemblies; #endregion #region 构造函数 /// <summary>
/// 初始化 WcfServiceManager 类的实例
/// </summary>
protected WcfServiceManager()
{
_serviceHostGroup = new ConcurrentDictionary<string, ServiceHost>();
_serviceHostTemp = new ConcurrentDictionary<string, ServiceHost>();
_assemblies = new List<Assembly>();
} #endregion #region 接口方法的实现 /// <summary>
/// 以指定的名称增加 WCF 服务实例,但是该服务并没有启动。
/// </summary>
/// <param name="serviceName">表示 WCF 服务的名称。</param>
/// <returns>返回布尔值,true 表示增加 WCF 服务成功,false 表示增加 WCF 失败。</returns>
public bool AddService(string serviceName)
{
if (string.IsNullOrEmpty(serviceName) || string.IsNullOrWhiteSpace(serviceName))
{
return false;
}
if (!_serviceHostGroup.ContainsKey(serviceName))
{
Type serviceType = GetServiceTypeFromAssemblies(serviceName,_assemblies);
if (serviceType != null)
{
ServiceHost host = new ServiceHost(serviceType);
_serviceHostGroup.TryAdd(serviceName, host);
return true;
}
else
{
return false;
}
}
return false;
} /// <summary>
/// 从容器对象中删除指定名称的 WCF 服务实例。
/// </summary>
/// <param name="serviceName">表示 WCF 服务的名称。</param>
/// <returns>返回布尔值,true 表示删除 WCF 服务成功,false 表示删除 WCF 服务失败。</returns>
public bool RemoveService(string serviceName)
{
if (string.IsNullOrEmpty(serviceName) || string.IsNullOrWhiteSpace(serviceName))
{
return false;
}
if (_serviceHostGroup.ContainsKey(serviceName))
{
ServiceHost hostInstance = null;
_serviceHostGroup.TryRemove(serviceName, out hostInstance);
if (hostInstance != null && hostInstance.State == CommunicationState.Opened)
{
hostInstance.Close();
hostInstance = null;
}
return true;
}
return false;
} /// <summary>
/// 获取所有的 WCF 服务实例的集合。
/// </summary>
/// <returns>返回所有的 WCF 服务实例集合。</returns>
public IEnumerable<WcfService> GetServices()
{
IList<WcfService> list = new List<WcfService>();
if (_serviceHostGroup != null && _serviceHostGroup.Count > )
{
foreach (var key in _serviceHostGroup.Keys)
{
var service = new WcfService();
service.ServiceName = _serviceHostGroup[key].Description.Name;
service.State = _serviceHostGroup[key].State;
service.Description = _serviceHostGroup[key].Description;
list.Add(service);
}
}
return list;
} /// <summary>
/// 根据指定的名称获取 WCF 服务实例。
/// </summary>
/// <param name="serviceName">表示 WCF 服务的名称。</param>
/// <returns>返回和指定名称相匹配的 WCF 服务实例,如果不存在则会返回 Null 值。</returns>
public WcfService GetService(string serviceName)
{
if (string.IsNullOrEmpty(serviceName) || string.IsNullOrWhiteSpace(serviceName))
{
throw new ArgumentNullException("要查找的 WCF 服务的名称不能为空!");
}
WcfService service = null;
if (_serviceHostGroup.ContainsKey(serviceName))
{
service = new WcfService();
service.ServiceName = _serviceHostGroup[serviceName].Description.Name;
service.State = _serviceHostGroup[serviceName].State;
service.Description = _serviceHostGroup[serviceName].Description;
return service;
}
return service;
} /// <summary>
/// 清空容器中所有 WCF 服务实例。
/// </summary>
public void ClearAll()
{
if (_serviceHostGroup != null && _serviceHostGroup.Count > )
{
this.CloseAll();
_serviceHostGroup.Clear();
}
} /// <summary>
/// 开启指定名称 WCF 服务实例,此时该服务可以为客户端提供服务了。
/// </summary>
/// <param name="serviceName">表示 WCF 服务的名称。</param>
/// <returns>返回布尔值,true 表示成功开启 WCF 服务,false 表示开启式 WCF 服务失败。</returns>
public bool Start(string serviceName)
{
if (string.IsNullOrEmpty(serviceName) || string.IsNullOrWhiteSpace(serviceName))
{
return false;
}
var serviceHost = _serviceHostGroup[serviceName];
if (serviceHost != null)
{
if (serviceHost.State == CommunicationState.Created && serviceHost.State != CommunicationState.Faulted)
{
serviceHost.Open();
return true;
}
else if (serviceHost.State == CommunicationState.Closed || serviceHost.State != CommunicationState.Faulted)
{
ServiceHost tempHost;
_serviceHostGroup.TryRemove(serviceName,out tempHost);
if (tempHost != null)
{
if (tempHost.State == CommunicationState.Opened)
{
tempHost.Close();
}
tempHost = null;
}
ServiceHost newhost = new ServiceHost(serviceHost.Description.ServiceType);
newhost.Open();
_serviceHostGroup.TryAdd(serviceName, newhost);
return true;
}
}
return false;
} /// <summary>
/// 开启所有的 WCF 服务实例。
/// </summary>
public void StartAll()
{
if (_serviceHostGroup != null && _serviceHostGroup.Count > )
{
foreach (ServiceHost host in _serviceHostGroup.Values)
{
if (host.State != CommunicationState.Opened)
{
if (host.State == CommunicationState.Closed)
{
ServiceHost newhost = new ServiceHost(host.Description.ServiceType);
newhost.Open();
_serviceHostTemp.TryAdd(host.Description.ConfigurationName, newhost);
}
else if (host.State == CommunicationState.Faulted)
{
ServiceHost newhost = new ServiceHost(host.Description.ServiceType);
newhost.Open();
_serviceHostTemp.TryAdd(host.Description.ConfigurationName, newhost);
}
else if (host.State == CommunicationState.Created)
{
host.Open();
}
}
}
}
if (_serviceHostTemp != null && _serviceHostTemp.Count > )
{
foreach (KeyValuePair<string, ServiceHost> item in _serviceHostTemp)
{
if (_serviceHostGroup.ContainsKey(item.Key))
{
if (_serviceHostGroup[item.Key].State == CommunicationState.Opened)
{
_serviceHostGroup[item.Key].Close();
}
ServiceHost tempHost;
_serviceHostGroup.TryRemove(item.Key,out tempHost);
if (tempHost.State != CommunicationState.Closed)
{
tempHost.Close();
tempHost = null;
}
if (item.Value.State == CommunicationState.Closed)
{
item.Value.Open();
}
_serviceHostGroup.TryAdd(item.Key, item.Value);
}
}
_serviceHostTemp.Clear();
}
} /// <summary>
/// 关闭指定名称的 WCF 服务实例,此时该服务就不能为客户端提供任何服务了。
/// </summary>
/// <param name="serviceName">表示 WCF 服务的名称。</param>
/// <returns>返回布尔值,true 表示成功关闭 WCF 服务实例,false 表示关闭 WCF 服务实例失败。</returns>
public bool Close(string serviceName)
{
if (string.IsNullOrEmpty(serviceName) || string.IsNullOrWhiteSpace(serviceName))
{
return false;
}
var host = _serviceHostGroup[serviceName];
if (host != null)
{
if (host.State == CommunicationState.Opened)
{
host.Close();
}
return true;
}
return false;
} /// <summary>
/// 关闭所有的 WCF 服务实例,停止所有的服务。
/// </summary>
public void CloseAll()
{
if (_serviceHostGroup != null && _serviceHostGroup.Count > )
{
foreach (ServiceHost host in _serviceHostGroup.Values)
{
if (host.State == CommunicationState.Opened)
{
host.Close();
}
}
}
} /// <summary>
/// 根据指定的名称来判断该 WCF 服务实例是否已经开启。
/// </summary>
/// <param name="serviceName">表示 WCF 服务的名称。</param>
/// <returns>返回布尔值,true 表示该名称的 WCF 服务实例是已经开启的,false 表示该名称的 WCF 服务实例是未开启的。</returns>
public bool IsStartup(string serviceName)
{
if (string.IsNullOrEmpty(serviceName) || string.IsNullOrWhiteSpace(serviceName))
{
return false;
}
var host = _serviceHostGroup[serviceName];
if (host != null)
{
if (host.State == CommunicationState.Opened)
{
return true;
}
}
return false;
} /// <summary>
/// 重新加载所有的 WCF 服务实例,并将所有的 WCF 服务对象开启
/// </summary>
public void Reload()
{
this.CloseAll();
this.ClearAll();
this.Initialize();
this.StartAll();
} /// <summary>
/// 获取 WCF 服务实例的个数
/// </summary>
public int Count
{
get
{
return _serviceHostGroup.Count;
}
} #endregion #region 定义的抽象方法 /// <summary>
/// 加载所有的 WCF 服务实例对象
/// </summary>
/// <param name="assemblyFullNames">承载 WCF 服务的应用程序集的完全限定名数组</param>
public void Initialize(params string[] assemblyFullNames)
{
_assemblyNames = assemblyFullNames;
CloseAll();
ClearAll(); var currentDomainDlls = GetAssembliesFromCurrentDomain();
var specifiedDlls = GetAssembliesFromSpecifiedCondition(_assemblyNames);
foreach (var item in currentDomainDlls)
{
_assemblies.Add(item);
}
foreach (var item in specifiedDlls)
{
_assemblies.Add(item);
} Configuration config = ConfigurationManager.OpenExeConfiguration(Assembly.GetEntryAssembly().Location);
ServiceModelSectionGroup serviceModelGroup = config.GetSectionGroup("system.serviceModel") as ServiceModelSectionGroup;
if (serviceModelGroup != null)
{
foreach (ServiceElement service in serviceModelGroup.Services.Services)
{
this.AddService(service.Name);
}
}
} /// <summary>
/// 根据指定的字符串类型的程序集名称列表获取强类型的程序集列表
/// </summary>
/// <returns>返回获取到的强类型的程序集列表</returns>
protected virtual IList<Assembly> GetAssembliesFromSpecifiedCondition(params string[] assemblyNames)
{
IList<Assembly> assemblies = new List<Assembly>();
if (assemblyNames != null && assemblyNames.Length > )
{
foreach (var item in assemblyNames)
{
var assembly = Assembly.Load(item);
assemblies.Add(assembly);
}
}
return assemblies;
} /// <summary>
/// 根据当前的应用程序域获取所有必需的程序集
/// </summary>
/// <returns>返回获取到当前应用程序域内的程序集列表</returns>
protected virtual IList<Assembly> GetAssembliesFromCurrentDomain()
{
IList<Assembly> assemblies = AppDomain.CurrentDomain.GetAssemblies().Where(a => (!a.FullName.StartsWith("System", StringComparison.OrdinalIgnoreCase) && (!a.FullName.StartsWith("Microsoft", StringComparison.OrdinalIgnoreCase)) && (!a.FullName.StartsWith("mscorlib", StringComparison.OrdinalIgnoreCase)) && (!a.FullName.StartsWith("vshost32", StringComparison.OrdinalIgnoreCase)) && (!a.FullName.StartsWith("SMDiagnostics", StringComparison.OrdinalIgnoreCase)))).ToList();
return assemblies;
} /// <summary>
/// 根据 WCF 服务的名称在当前程序域中或者传入的程序集中查找该服务的 Type 类型的对象
/// </summary>
/// <param name="serviceName">要查找的 WCF 服务的名称</param>
/// <param name="assemblies">承载 WCF 服务的程序集列表</param>
/// <returns>返回WCF服务的Type类型的对象,如果没有找到相应的类型就会返回 Null 值。</returns>
private Type GetServiceTypeFromAssemblies(string serviceName, IList<Assembly> assemblies)
{
if (string.IsNullOrEmpty(serviceName) || string.IsNullOrWhiteSpace(serviceName))
{
throw new ArgumentNullException("要查找的 WCF 服务的名称");
} if (assemblies == null || assemblies.Count == )
{
throw new ArgumentNullException("待查找的程序集列表不能为空!");
} try
{
if (assemblies != null && assemblies.Count() > )
{
var currentAssembly = assemblies.FirstOrDefault(a => a.GetType(serviceName) != null);
if (currentAssembly != null)
{
return currentAssembly.GetType(serviceName);
}
}
}
catch (Exception)
{
throw;
}
return null;
} #endregion #region IDispoable模式 /// <summary>
/// 释放托管资源
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
} /// <summary>
/// 析构函数释放资源
/// </summary>
~WcfServiceManager()
{
Dispose(false);
} /// <summary>
/// 释放所有的托管资源和非托管资源核心方法实现
/// </summary>
/// <param name="disposing">是否需要释放那些实现IDisposable接口的托管对象</param>
protected virtual void Dispose(bool disposing)
{
if (_disposed)
{
return; //如果已经被回收,就中断执行
}
if (disposing)
{
//TODO:回收托管资源,调用IDisposable的Dispose()方法就可以
this.CloseAll();
this.ClearAll();
_serviceHostGroup = null;
}
//TODO:释放非托管资源,设置对象为null
_disposed = true;
} #endregion
}
3、真正实现的叶子结点类型设计,类型是:DefaultWcfServiceManager.cs
该类型就是用户将要使用的类型。
/// <summary>
/// WCF 服务的实例管理器,该类型可以实现对容器内部的 WCF 服务对象进行增加、删除、查询、开启和关闭的操作。
/// </summary>
public sealed class DefaultWcfServiceManager:WcfServiceManager, IDisposable
{
#region 构造函数 /// <summary>
/// 初始化 DefaultWcfServiceManager 类型的实例
/// </summary>
public DefaultWcfServiceManager(){ } #endregion
}
主要的类型就差不多了。在这个设计过程中,还会涉及到一个辅助类型 WcfService
4、辅助类型 WcfService 的设计编码。很简单,直接上代码。
/// <summary>
/// WCF 服务实例的类型的定义
/// </summary>
public sealed class WcfService
{
#region 私有字段 private string _serviceName;
private CommunicationState _communicationState;
private ServiceDescription _serviceDescription; #endregion #region 构造函数 /// <summary>
/// 初始化 WcfService 类型的实例
/// </summary>
public WcfService()
{ } #endregion #region 实例属性 /// <summary>
/// 获取或者设置 WCF 服务实例的名称
/// </summary>
public string ServiceName
{
get { return _serviceName; }
set
{
if ((!string.IsNullOrEmpty(value)) && (!string.IsNullOrWhiteSpace(value)))
{
_serviceName = value;
}
}
} /// <summary>
/// 获取或者设置 WCF 的服务实例的运行状态
/// </summary>
public CommunicationState State
{
get { return _communicationState; }
set { _communicationState = value; }
} /// <summary>
/// 获取或者设置 WCF 服务的描述信息
/// </summary>
public ServiceDescription Description
{
get { return _serviceDescription; }
set
{
if (value != null)
{
_serviceDescription = value;
}
}
} #endregion
}
5、单元测试项目代码。
这是最后的代码了,有源码没有测试代码,似乎还少一点。测试代码如下:
class Program
{
static void Main(string[] args)
{
//DefaultWcfServiceManager hosts = new DefaultWcfServiceManager("ServiceInstance, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null");
DefaultWcfServiceManager hosts = new DefaultWcfServiceManager();
hosts.Initialize("ServiceInstance, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null");
//hosts.Initialize("ServiceInstance");
string operation = "a";
do
{
operation = Console.ReadLine();
if (string.Compare(operation, "StartAll", true) == )
{
hosts.StartAll();
Console.WriteLine("已经全部打开");
} if (string.Compare(operation, "ConsoleService", true) == )
{
hosts.Close("ServiceInstance.ConsoleService");
Console.WriteLine("ConsoleService 已经关闭");
} if (string.Compare(operation, "ConsoleServiceOpen", true) == )
{
hosts.Start("ServiceInstance.ConsoleService");
Console.WriteLine("ConsoleService 已经打开");
} if (string.Compare(operation, "MathServiceOpen", true) == )
{
hosts.Start("ServiceInstance.MathService");
Console.WriteLine("MathService 已经打开");
} if (string.Compare(operation, "MathService", true) == )
{
hosts.Close("ServiceInstance.MathService");
Console.WriteLine("MathService 已经关闭");
} if (string.Compare(operation, "CloseAll", true) == )
{
hosts.CloseAll();
Console.WriteLine("已经全部关闭");
} if (string.Compare(operation, "Reload", true) == )
{
hosts.Reload();
Console.WriteLine("已经全部重新打开");
}
if (string.Compare(operation, "print", true) == )
{
foreach (var item in hosts.GetServices())
{
Console.WriteLine("服务地址:" + item.Description.Endpoints[].Address.Uri.ToString() + ";状态:" + item.State.ToString());
}
}
} while (string.Compare(operation, "exit", true) != );
}
}
总结:
好了,就写到这里吧。要想使用 WCF ,必须的命名空间是必须要引入的 System.ServiceModel,当然这里省略了必要的配置数据了,我相信,这个不是很难。也要说明一点,我这个项目是放在类库里面的,WCF 是分为 Client 端和 Server 端的,今天只是贴出了服务器端的代码,如果有需要,在把客户端生成代理类的代码贴出来。年尾了,让不好的东西过去,让自己迎接新的明天,不忘初心,继续努力。
WCF 服务的集合管理器的设计的更多相关文章
- [连载]《C#通讯(串口和网络)框架的设计与实现》-4.设备驱动管理器的设计
目 录 第四章 设备驱动管理器的设计... 2 4.1 接口定义... 2 4.2 设备容器... 7 4.3 ...
- 老徐FrankXuLei 受邀为花旗银行讲授《微软WCF服务分布式开发与SOA架构设计课程》
老徐FrankXuLei 受邀为花旗银行上海研发中心讲授<微软WCF服务分布式开发与SOA架构设计课程> 受邀为花旗银行上海研发中心讲授<微软WCF服务分布式开发与SOA架构设计课程 ...
- 用C#语言编写:集合管理器
static void Main(string[] args) { List<int> numbers = new List<int>(); ...
- Windows服务安装、卸载、启动和关闭的管理器
最近在重构公司的系统,把一些需要独立执行.并不需要人为关注的组件转换为Windows服务,Windows服务在使用的过程中有很多好处,相信这一点,就不用我多说了.但是每次都要建立Windows服务项目 ...
- Python 的上下文管理器是怎么设计的?
花下猫语:最近,我在看 Python 3.10 版本的更新内容时,发现有一个关于上下文管理器的小更新,然后,突然发现上下文管理器的设计 PEP 竟然还没人翻译过!于是,我断断续续花了两周时间,终于把这 ...
- tomcat会话之持久化会话管理器
前面提到的标准会话管理器已经提供了基础的会话管理功能,但在持久化方面做得还是不够,或者说在某些情景下无法满足要求,例如把会话以文件或数据库形式存储到存储介质中,这些都是标准会话管理器无法做到的,于是另 ...
- EBS Concurrent Manager(并发管理器)异常处理[final]
来自:http://blog.itpub.net/35489/viewspace-742191/ 有时候我们在通过 adstpall.sh 关闭应用后,然后再使用adstrtal.sh开启.发现并发 ...
- [转]SQL Server 2008 如何配置报表管理器
本文转自:https://docs.microsoft.com/zh-cn/previous-versions/sql/sql-server-2008/cc281384%28v%3dsql.100%2 ...
- Windows RestartManeger重启管理器
介绍 重启管理器API可以消除或是减少在完成安装或是更新的过程中系统需要重启的次数.软件安装或是更新过程之所以需要重启系统的原因在于一些需要更新的文件正在被运行中的程序或服务使用.而重启管理器可以 ...
随机推荐
- Java高级框架——Mybatis(二)
十.三种查询方式 1. selectList()返回值为List<resultType属性控制> 1.1 适用于查询结果都需要遍历的需求 List<Flower> list = ...
- react-native shadow失效
做边框阴影,但是有时候会失效,内容产生阴影,而边框无效,今天发现了原因,没错,就是没有设置背景颜色导致的.如图
- intellij idea工具 DeBug调试
断点的设定和eclipse一样,只要点一下就可以,下面是我设定的几个断点,再下面的三个窗口是用来调试代码的,这个和eclipse类似 调试常用的快捷键 F9 resume programe 恢复程序 ...
- C 语言 优先级
最高1 优先级举例 -a
- visual studio split edit window 编辑器窗口分屏
OR
- Java8 Base64
转自:https://www.runoob.com/java/java8-base64.html 在Java 8中,Base64编码已经成为Java类库的标准. Java 8 内置了 Base64 编 ...
- group_concat_max_len
SET SESSION group_concat_max_len = 1000000; SELECT GROUP_CONCAT(a.label_number SEPARATOR ',') FROM ( ...
- Mysql分表:Merge
merge是Mysql最简单的一种分表,Mysql自带的一个分表功能,Merge表并不保存数据,Merge表和分表是对应映射关系.demo: 创建分表:CREATE TABLE `user1` ( ` ...
- Jenkins问题笔记
1.启动docker容器权限不足 通过如下命令启动docker容器后,使用命令"docker logs -f jenkins"查看jenkins容器日志, docker run - ...
- javaSE基础知识
JVM,JRE,JDK三者的简单总结 1.见名解释 Java虚拟机(JVM):Java virtual machine简称JVM:“virtual”中文意思“虚拟的”,“machine”中文意思“机器 ...