C# - Common Tool

Json

涉及命名空间

using System.IO;
using System.Net;
using System.Runtime.Serialization.Json;
using Newtonsoft.Json;

序列化、反序列化、Post/Get方法

public class JsonOperation
{
	/// <summary>
	/// 序列化对象成JSON
	/// </summary>
	/// <param name="item"></param>
	/// <returns></returns>
	public static string ObjectSerialize(Object item)
	{
		DataContractJsonSerializer serializer = new DataContractJsonSerializer(item.GetType());
		using (MemoryStream ms = new MemoryStream())
		{
			serializer.WriteObject(ms, item);
			StringBuilder stringBuilder = new StringBuilder();
			stringBuilder.Append(Encoding.UTF8.GetString(ms.ToArray()));
			return stringBuilder.ToString();
		}
	}

	/// <summary>
	/// JSON反序列化
	/// </summary>
	public static T JsonDeserialize<T>(string jsonString)
	{
		DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T));
		using (MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString)))
		{
			T obj = (T)ser.ReadObject(ms);
			return obj;
		}
	}

	/// <summary>
	/// post方法
	/// </summary>
	/// <param name="url">地址</param>
	/// <param name="json">json对象</param>
	/// <param name="resultValue">返回的string类型的JSON字符串</param>
	/// <returns></returns>
	public static bool PostJson(string url, string json, out string resultValue, out string errMsg)
	{
		errMsg = "";
		// 创建一个HTTP请求  
		HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
		resultValue = "";
		request.Method = "POST";// Post请求方式 
		request.ContentType = "application/json";// 内容类型
		// 将Json字符串转化为字节  
		byte[] payload = System.Text.Encoding.UTF8.GetBytes(json);
		request.ContentLength = payload.Length;// 设置请求的ContentLength
		
		// 发送请求,获得请求流  
		Stream writer;
		try
		{
			writer = request.GetRequestStream();// 获取用于写入请求数据的Stream对象
		}
		catch (Exception)
		{
			writer = null;
			errMsg = "连接服务器失败!";
			return false;
		}            
		writer.Write(payload, 0, payload.Length);// 将请求参数写入流
		writer.Close();

		// strValue为http响应所返回的字符流
		HttpWebResponse response = null;
		Stream stream = null;
		StreamReader myStreamReader = null;
		try
		{
			response = (HttpWebResponse)request.GetResponse();// 获得响应流
			stream = response.GetResponseStream();
			myStreamReader = new StreamReader(stream, Encoding.UTF8);
			resultValue = myStreamReader.ReadToEnd();
			return true;
		}
		catch (WebException ex)
		{
			response = ex.Response as HttpWebResponse;
			errMsg = "调用PostJson方法异常:" + ex.Message;
			return false;
		}
		finally
		{
			if (stream != null)
			{
				stream.Close();
				stream.Dispose();
			}
			if (myStreamReader != null)
			{
				myStreamReader.Close();
				myStreamReader.Dispose();
			}
			if (response != null)
			{
				response.Close();
			}
		}
	}

	/// <summary>
	/// get方法
	/// </summary>
	/// <param name="url">地址</param>
	/// <param name="resultValue">返回的string类型的JSON字符串</param>
	/// <returns></returns>
	public static bool GetJson(string url, out string resultValue, out string errMsg)
	{
		errMsg = "";
		resultValue = "";
		Encoding encoding = Encoding.UTF8;
		HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
		request.Method = "GET";
		request.Accept = "text/html, application/xhtml+xml, */*";
		request.ContentType = "application/json";
		
		HttpWebResponse response = null;
		try
		{
			response = (HttpWebResponse)request.GetResponse();
			using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
			{
				resultValue = reader.ReadToEnd();
			}
			return true;
		}
		catch (Exception e)
		{
			errMsg = "调用GetJson方法异常:" + e.Message;
			return false;
		}
		finally
		{
			if (response != null)
			{
				response.Close();
			}
		}
	}
}

其中,using Newtonsoft.Json 需要引用 Newtonsoft.Json.dll。在进行Json格式数据传输时,通常涉及到:DataContractJsonSerializerJavaScriptSerializer Json.Net。Json.Net 即 Newtonsoft.Json,非微软类库,开源的世界级Json操作类库,性能以及通用性较好。

50% faster than DataContractJsonSerializer, and 250% faster than JavaScriptSerializer

详细信息参考:Json.Net

利用 Json.Net 序列化/反序列化

/// <summary>
/// 序列化对象成JSON
/// </summary>
public static string SerializeByJsonNet(Object item)
{
	// JsonSerializerSettings 序列化配置
	// Formatting 格式配置
	return JsonConvert.SerializeObject(item);
}
/// <summary>
/// JSON反序列化
/// </summary>
public static T DeserializeByJsonNet<T>(string jsonString)
{
	// JsonSerializerSettings 序列化配置
	return JsonConvert.DeserializeObject<T>(jsonString);
}

序列化时,指定字段:[JsonProperty],忽略字段:[JsonIgnore]

也可以通过如下辅助类,通过传入props数组指定或忽略某些字段

/// <summary>
/// Summary description for LimitPropsContractResolver
/// </summary>
public class LimitPropsContractResolver : DefaultContractResolver
{
    string[] props = null;
    bool retain;

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="props">传入的属性数组</param>
    /// <param name="retain">true:表示props是需要保留的字段  false:表示props是要排除的字段</param>
    public LimitPropsContractResolver(string[] props, bool retain = true)
    {
        //指定或剔除序列化属性的清单
        this.props = props;
        this.retain = retain;
    }

    protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
    {
        IList<JsonProperty> list = base.CreateProperties(type, memberSerialization);

        //只[保留或剔除]清单有列出的属性
        return list.Where(p => {
            if (retain)
            {
                return props.Contains(p.PropertyName);
            }
            else
            {
                return !props.Contains(p.PropertyName);
            }
        }).ToList();
    }
}

调用方式如下

var jSetting = new JsonSerializerSettings {
    NullValueHandling = NullValueHandling.Ignore
};
jSetting.ContractResolver = new LimitPropsContractResolver(props, false);
return JsonConvert.SerializeObject(item, Formatting.None, jSetting);

若待序列化对象包含DateTime类型字段属性时请用该方法

public static string SerializeWithDateTime(object data, string DateTimeFormats = "yyyy-MM-dd HH:mm:ss")
{
    var timeConverter = new Newtonsoft.Json.Converters.IsoDateTimeConverter {
            DateTimeFormat = DateTimeFormats
        };

    return JsonConvert.SerializeObject(data, Formatting.Indented, timeConverter);
}

序列化 Dictionary<> 或 Hashtable、DataTable 时,推荐使用 Json.Net。否则,json 字符串格式有问题

// Json.Net
{"beijing":"001","shanghai":"002"}
// DataContractJsonSerializer
[{"Key":"beijing","Value":"001"},{"Key":"shanghai","Value":"002"}]

关于 Json.Net 的其他用法,具体参考:Newtonsoft.Json的高级用法

除此之外,还可以用 Linq to Json 定向解析需要的数据,实现快速查询、修改和创建 Json 对象。

JObject:用来生成一个JSON对象,简单来说就是生成”{}”
JArray:用来生成一个JSON数组,也就是”[]”
JProperty:用来生成一个JSON数据,格式为key/value的值

深入详细信息参见:Querying JSON with LINQ

Xml

涉及命名空间

using System.IO;
using System.Xml;
using System.Xml.Serialization;
using System.Xml.Linq;
using System.Xml.XPath;

对象和XML字符串相互转化

/// <summary>
/// UTF8字节数组 ---> 字符串
/// </summary> 
private static string UTF8BytesToString(byte[] bytes)
{
	UTF8Encoding encoding = new UTF8Encoding();
	return (encoding.GetString(bytes));
}
/// <summary>
/// 字符串 ---> UTF8字节数组
/// </summary>
private static byte[] StringToUTF8Bytes(String pXmlString)
{
	UTF8Encoding encoding = new UTF8Encoding();
	return (encoding.GetBytes(pXmlString));
}

/// <summary>
/// 数据对象转换成XML字符串
/// </summary>
private static string SerializeObject(object obj, Type type)
{
	string XmlizedStr = string.Empty;
	MemoryStream ms = null;
	XmlTextWriter xtw = null;

	try
	{
		ms = new MemoryStream();
		xtw = new XmlTextWriter(ms, Encoding.UTF8);
		XmlSerializer xs = new XmlSerializer(type);
		xs.Serialize(xtw, obj);
		ms = (MemoryStream)xtw.BaseStream;
		XmlizedStr = UTF8BytesToString(ms.ToArray());
		return XmlizedStr;
	}
	catch (Exception ex)
	{
		return "";
	}
	finally
	{
		// 释放资源
		if (xtw != null)
		{
			xtw.Close();
			ms.Close();
			ms.Dispose();
		}
	}
}
/// <summary>
/// xml字符串转换数据对象 
/// </summary>
private static object DeserializeObject(string XmlizedStr, Type type)
{
	MemoryStream ms = null;
	XmlTextWriter xtw = null;

	try
	{
		XmlSerializer xs = new XmlSerializer(type);
		ms = new MemoryStream(StringToUTF8Bytes(XmlizedStr));
		xtw = new XmlTextWriter(ms, Encoding.UTF8);
		return xs.Deserialize(ms);
	}
	catch (Exception ex)
	{
		return null;
	}
	finally
	{
		// 释放资源
		if (xtw != null)
		{
			xtw.Close();
			ms.Close();
			ms.Dispose();
		}
	}
}

Internet

涉及命名空间

using System.Net;
using System.Net.Sockets;
// 方法1:Net2.0新增类库
using System.Net.NetworkInformation;
// 方法2:外部方法
using System.Runtime.InteropServices;

测试网络连通性、端口是否正常

/// <summary>
/// 获取主机名
/// </summary>
public static string GetHostname()
{
	return System.Net.Dns.GetHostName();
}
/// <summary>
/// 主机名 ---> IP
/// </summary>
public static string GetIpByHostname(string hostname)
{
	if (string.IsNullOrWhiteSpace(hostname)) {
		return "";
	}

	try
	{
		System.Net.IPHostEntry host = System.Net.Dns.GetHostEntry(hostname);
		return host.AddressList.GetValue(0).ToString();
	}
	catch (Exception ex)
	{
		return null;
	}
}
/// <summary>
/// IP ---> 主机名
/// </summary>
public static string GetHostnameByIp(string ip)
{
	if (string.IsNullOrWhiteSpace(ip)) {
		return "";
	}

	try
	{
		System.Net.IPHostEntry host = System.Net.Dns.GetHostEntry(ip);
		return host.HostName;
	}
	catch (Exception ex)
	{
		return null;
	}
}

/// <summary>
/// 只是测试网络连通性,不能检测端口
/// (C#实现ping的基本方法)
/// </summary>
/// 方法1 基于TCP/IP协议访问 ///
public static bool PingIpOrDomainName(string strIpOrDName)
{
	try
	{
		Ping pingSender = new Ping();
		PingOptions pingOpts = new PingOptions();
		pingOpts.DontFragment = true;

		int intTimeout = 60;
		string data = "";
		byte[] buffer = Encoding.UTF8.GetBytes(data);
		PingReply pingReply = pingSender.Send(strIpOrDName, intTimeout, buffer, pingOpts);
		
		string strInfo = pingReply.Status.ToString();               
		if (strInfo == "Success")
		{
			return true;
		}
		else
		{
			return false;
		}
	}
	catch (Exception)
	{
		return false;
	}
}
/// 方法2 ///
public static bool PingIpOrDomainName2(string strIpOrDName)
{ 
	int Description = 0;
	return InternetGetConnectedState(Description, 0);
}
[DllImport("wininet.dll")]
private extern static bool InternetGetConnectedState(int Description, int ReservedValue);

/// <summary>
/// 具体到某个端口是否联通的
/// (C#实现telnet的基本方法)
/// </summary>
public static bool ConnectTest(string ip, int port)
{
	IPAddress ipAddr = IPAddress.Parse(ip);
	try
	{
		IPEndPoint point = new IPEndPoint(ipAddr, port);
		Socket sock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
		sock.Connect(point);
		Console.WriteLine("连接端口{0}成功!", point);

		//sock.Disconnect(true);
		sock.Shutdown(SocketShutdown.Both);
		sock.Close();
		sock = null;
	}
	catch (SocketException e)
	{
		if (e.ErrorCode != 10061)
		{
			Console.WriteLine(e.Message);
		}
		return false;
	}
	return true;
}

直接在命令行窗口测试亦可

ping IP地址
telnet IP地址 Port

Cache

业务中需要在前端缓存卡图片,顺带了解下几种缓存的实现方式

首先需要引用命名空间

using System.Runtime.Caching;
using System.Windows.Threading;

(1)字典集 + 定时器

/// <summary>
/// 基于字典集的缓存帮助类
/// </summary>
public class CacheHelper
{
    // 缓存字典集
    private static IDictionary<string, object> cacheDic = new Dictionary<string, object>();
    // key-->Timer
    private static IDictionary<string, object> keyToTimerDict = new Dictionary<string, object>();
    // Timer-->key
    private static IDictionary<object, object> timerToKeyDict = new Dictionary<object, object>();

    public static bool Contains(string _key)
    { 
        return cacheDic.ContainsKey(_key);
    }

    public static void Set(string _key, Object obj, TimeSpan? expireTimeSpan = null)
    {
        if (string.IsNullOrWhiteSpace(_key))
        {
            throw new ArgumentException("Set||key不允许为空");
        }

        cacheDic[_key] = obj;

        if (expireTimeSpan.HasValue)
        {
            DispatcherTimer timer = new DispatcherTimer();
            keyToTimerDict.Add(_key, timer);
            timerToKeyDict.Add(timer, _key);
            timer.Tick += new EventHandler(RecycleKey);
            timer.Interval = expireTimeSpan.Value;
            timer.Start();
        }
    }

    public static Object Get(string _key)
    {
        if (string.IsNullOrWhiteSpace(_key))
        {
            throw new ArgumentException("Get||key不允许为空");
        }

        if (Contains(_key))
        {
            return cacheDic[_key];
        }
        return null;
    }

    public static void Remove(string _key)
    {
        if (string.IsNullOrWhiteSpace(_key))
        {
            throw new ArgumentException("Remove||key不允许为空");
        }

        if (Contains(_key))
        {
            cacheDic.Remove(_key);
            if (keyToTimerDict.ContainsKey(_key))
            {
                keyToTimerDict.Remove(_key);
                RemoveTimer((DispatcherTimer)timerToKeyDict[_key]);
            }
        }
    }

    private static void RemoveTimer(DispatcherTimer _timer)
    {
        if (timerToKeyDict.ContainsKey(_timer))
        {
            timerToKeyDict.Remove(_timer);
            _timer.Stop();
            _timer = null;
        }
    }

    private static void RecycleKey(object o, EventArgs e)
    { 
        string key = (string)timerToKeyDict[(DispatcherTimer)o];
        Remove(key);
    }

    public static void RemoveAll()
    {
        foreach (string key in cacheDic.Keys)
        {
            if (keyToTimerDict.ContainsKey(key))
            {
                keyToTimerDict.Remove(key);
                RemoveTimer((DispatcherTimer)timerToKeyDict[key]);
            }
        }

        cacheDic.Clear();
    }
}

(2)MemoryCache + CachePolicy

注意在get()前,先用Contains()检查键key是否存在。

/// <summary>
/// 基于系统MemoryCache的缓存帮助类
/// </summary>
public class MemoryCacheHelper
{
    ///内部锁对象
    private static readonly object _lockerObj = new object();

    public static bool Contains(string _key)
    {
        return MemoryCache.Default.Contains(_key);
    }

    /// <param name="expireTimeSpan">相对到期时间段</param>
    /// <param name="expireDateTime">绝对到期时间点</param>
    public static void Set(string _key, Object obj,
        TimeSpan? expireTimeSpan = null, DateTime? expireDateTime = null)
    {
        if (string.IsNullOrWhiteSpace(_key))
        {
            throw new System.ArgumentException("Set||key不能为空!");
        }

        CacheItem item = new CacheItem(_key, obj);
        CacheItemPolicy policy = CreateCachePolicy(expireTimeSpan, expireDateTime);            
            
        lock (_lockerObj)
        {
            MemoryCache.Default.Set(item, policy);
        }
    }

    // Get前,先用Contains判断
    public static T Get<T>(string _key)
    { 
        if (string.IsNullOrWhiteSpace(_key))
		{
			throw new System.ArgumentException("Get||key不能为空!");
		}

        return (T)((object)MemoryCache.Default[_key]);    
    }

    public static void Remove(string _key)
    {
        if (string.IsNullOrWhiteSpace(_key))
        {
            throw new System.ArgumentException("Remove||key不能为空!");
        }

        if (Contains(_key))
        {
            MemoryCache.Default.Remove(_key);
        }
    }

    public static void RemoveAll()
    {
        while (MemoryCache.Default.GetCount() > 0L)
        {
            Remove(MemoryCache.Default.ElementAt(0).Key);
        }
    }

    private static CacheItemPolicy CreateCachePolicy(TimeSpan? expireTimeSpan = null, DateTime? expireDateTime = null)
    {
        CacheItemPolicy policy = new CacheItemPolicy();
            
        if (expireDateTime.HasValue)
        {
            policy.AbsoluteExpiration = expireDateTime.Value;
        }
        else if (expireTimeSpan.HasValue)
        {
            policy.SlidingExpiration = expireTimeSpan.Value;
        }
        policy.Priority = CacheItemPriority.Default;
            
        return policy;
    }
}

也可以直接使用系统自带的MemoryCache类。

对系统自带的缓存策略CacheItemPolicy的几个属性了解下

/// <summary>
/// 缓存策略
/// </summary>
public class CacheItemPolicy
{
    // 摘要: 获取或设置一个值,该值指示是否应在指定持续时间过后逐出某个缓存项
    // 返回结果:在逐出某个缓存项之前必须经过的时间段,默认Caching.ObjectCache.InfiniteAbsoluteExpiration
    public DateTimeOffset AbsoluteExpiration { get; set; }
    // 摘要: 获取或设置一个值,该值指示如果某个缓存项在给定时段内未被访问,是否应被逐出
    // 返回结果:一个时段,必须在此时段内访问某个缓存项,否则将从内存中逐出该缓存项。默认Caching.ObjectCache.NoSlidingExpiration
    public TimeSpan SlidingExpiration { get; set; }
        
    // 摘要: 委托引用,从缓存中移除某个项后调用该委托
    public CacheEntryUpdateCallback UpdateCallback { get; set; }
    // 摘要: 委托引用,从缓存中移除某个缓存项之前调用该委托
    public CacheEntryRemovedCallback RemovedCallback { get; set; }
}

给出实际使用时的几种形式,仅供参考

public class CacheOperation
{
    // RVC.SLBase:前端框架缓存(随当前运行程序的存在周期)
    public static void SetCacheWay(string key, Object obj, TimeSpan span)
    {
        CacheHelper.Set(key, obj, span);
    }
    public static Object GetCacheWay(string key)
    {
        return CacheHelper.Get(key);
    }

    // RVC.MVCBase:内存缓存-1
    public static void SetCacheWay1(string key, Object obj, int Cache_Minutes)
    {
        MemoryCache cache = MemoryCache.Default;
        cache[key] = obj;

        CacheItemPolicy policy = new CacheItemPolicy();
        policy.AbsoluteExpiration = DateTimeOffset.Now.AddMinutes(Cache_Minutes);
        cache.Add(key, obj, policy);
    }
    public static Object GetCacheWay1(string key)
    {
        MemoryCache cache = MemoryCache.Default;
        return cache[key];
    }

   // RVC.MVCBase:内存缓存-2
   // 高级版的MemoryCache实现
   public static void SetCacheWay2(string key, Object obj, 
	  TimeSpan? expireTimeSpan = null, DateTime? expireDateTime = null)
   {
	   MemoryCacheHelper.Set(key, obj, expireTimeSpan, expireDateTime);
   }
   public static Object GetCacheWay2(string key)
   {
	  if (MemoryCacheHelper.Contains(key))
	  {
		 return MemoryCacheHelper.Get<object>(key);
	  }
	  else
	  {
	  	 return null;
	  }
   }
}

其中,对于如下特例,实际生命时长只有5秒:绝对到期时间优先级高于相对到期时间

CacheOperation.SetCacheWay2("KEY", "VALUE", 
         new TimeSpan(0, 0, 60), DateTime.Now.AddSeconds(5));

关于 HttpContext的问题,参见:https://www.cnblogs.com/wjcx-sqh/p/11093956.html

Timer

工作中对定时器的应用颇多,对几种定时器做简单的梳理

/// 线程池执行
// System.Threading.Timer
private static System.Threading.Timer _timer1 = 
    new System.Threading.Timer(ExecuteAction1, null, 0, 2000);
private static void ExecuteAction1(object sender)
{
    Console.WriteLine("ExecuteAction1():[{0}] " + DateTime.Now.ToString(), Thread.CurrentThread.ManagedThreadId);
}  


/// 线程池执行  
// System.Timers.Timer
private static System.Timers.Timer _timer2 = 
    new System.Timers.Timer();
_timer2.Interval = 1000;
_timer2.Elapsed += new ElapsedEventHandler(ExecuteAction2); 
private static void ExecuteAction2(object sender, ElapsedEventArgs e)
{
    Console.WriteLine("ExecuteAction2():[{0}] " + DateTime.Now.ToString(), Thread.CurrentThread.ManagedThreadId);
}  


/// 最宜用于页面定时(Tick事件在主线程中执行) 
// System.Windows.Threading.DispatcherTimer
private static System.Windows.Threading.DispatcherTimer _timer3 =   
    new System.Windows.Threading.DispatcherTimer();
_timer3.Interval = TimeSpan.FromSeconds(2);
_timer3.Tick += new EventHandler(ExecuteAction3);  
private static void ExecuteAction3(object sender, EventArgs e)
{
    Console.WriteLine("ExecuteAction3():" + DateTime.Now.ToString());
}


/// 最宜用于Windows窗体应用程序中,并且必须在窗口中使用(事件线程与主窗体的线程是同一个)  
// System.Windows.Forms.Timer
private static System.Windows.Forms.Timer _timer4 =   
    new System.Windows.Forms.Timer();
_timer4.Interval = 2000;
_timer4.Tick += new EventHandler(ExecuteAction4);   
private static void ExecuteAction4(object sender, EventArgs e)
{
    Console.WriteLine("ExecuteAction4():" + DateTime.Now.ToString());
}  

参考[C#].NET中几种Timer的使用

计时器

精确计算目标程序,特别是多线程程序的性能。

QueryPerformanceFrequency:从硬件的实时计算器获取主频频率

QueryPerformanceCounte:从硬件的实时计算器中获取当前计数值,实时计算器由硬件驱动和进程线程无关

public static class QueryPerformanceMethd
{
    [DllImport("kernel32.dll")]
    public extern static short QueryPerformanceCounter(ref long x);
    [DllImport("kernel32.dll")]
    public extern static short QueryPerformanceFrequency(ref long x);
}

关于具体使用可参见:https://www.cnblogs.com/Van-Bumblebee/p/5483432.html

在定时前先调用QueryPerformanceFrequency()函数获得机器内部计时器的时钟频率,再前后分别调用QueryPerformanceCounter(),利用两次计数之差和时钟频率,可计算出事件经历的精确时间。

C#中几种常见计时器,可供参考。

 

转载于:https://www.cnblogs.com/wjcx-sqh/p/8288487.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值