標籤:rpo zh-cn delegate his sys md5 eve lazy send
樣本
使用方法
參考
樣本
以下一個簡單的非同步事件TCP用戶端實現
using Newtonsoft.Json;using Newtonsoft.Json.Linq;using System;using System.Collections.Generic;using System.ComponentModel;using System.Linq;using System.Net.Sockets;using System.Text;using System.Text.RegularExpressions;using System.Threading;namespace Leestar54{ /// <summary> /// 自訂回調事件參數 /// </summary> /// <typeparam name="T">泛型類返回</typeparam> public class TEventArgs<T> : EventArgs { public T Result { get; private set; } public TEventArgs(T obj) { this.Result = obj; } } class MyTcpClient { private string md5id; Thread readThread; Thread heartbeatThread; TcpClient tcpClient; NetworkStream ns; //AsyncOperation會在建立他的上下文執行回調 public AsyncOperation AsyncOperation; private static MyTcpClient singleton = null; static readonly object lazylock = new object(); #region Event //回調代理中處理事件 public event EventHandler Connected; public event EventHandler<TEventArgs<JObject>> Receive; public event EventHandler<TEventArgs<Exception>> Error; //AsyncOperation回調代理 private SendOrPostCallback OnConnectedDelegate; private SendOrPostCallback OnReceiveDelegate; private SendOrPostCallback OnErrorDelegate; private void OnConnected(object obj) { Connected?.Invoke(this, EventArgs.Empty); } private void OnReceive(object obj) { Receive?.Invoke(this, new TEventArgs<JObject>((JObject)obj)); } private void OnError(object obj) { Error?.Invoke(this, new TEventArgs<Exception>((Exception)obj)); } #endregion /// <summary> /// 建構函式 /// </summary> MyTcpClient() { OnConnectedDelegate = new SendOrPostCallback(OnConnected); OnReceiveDelegate = new SendOrPostCallback(OnReceive); OnErrorDelegate = new SendOrPostCallback(OnError); } /// <summary> /// 單例模式 /// </summary> /// <returns></returns> public static MyTcpClient getInstance() { if (singleton == null) { lock (lazylock) { if (singleton == null) { singleton = new MyTcpClient(); } } } return singleton; } //當前用戶端唯一id public string Md5id { get { return md5id; } set { md5id = value; } } /// <summary> /// 串連伺服器 /// </summary> public void Connect() { try { tcpClient = new TcpClient("119.23.154.150", 9501); if (tcpClient.Connected) { ns = tcpClient.GetStream(); //開啟兩個線程長串連,一個讀取,一個心跳 readThread = new Thread(Read); readThread.IsBackground = true; readThread.Start(); heartbeatThread = new Thread(HeartBeat); heartbeatThread.IsBackground = true; heartbeatThread.Start(); System.Diagnostics.Debug.WriteLine("伺服器串連成功"); this.SendMsg(JObject.FromObject(new { cmd = "connect" })); } } catch (Exception e) { this.AsyncOperation.Post(OnErrorDelegate, e); Thread.Sleep(5000); ReConnect(); } } /// <summary> /// 讀取接收到的資料 /// </summary> private void Read() { try { //休眠2秒讓視窗初始化 Thread.Sleep(2000); Byte[] readBuffer = new Byte[1024]; while (true) { int alen = tcpClient.Available; if (alen > 0) { Int32 bytes = ns.Read(readBuffer, 0, alen); string responseData = System.Text.Encoding.UTF8.GetString(readBuffer, 0, bytes); //為了避免粘包現象,以\r\n作為分割符 string[] arr = responseData.Split("\r\n".ToCharArray(), StringSplitOptions.RemoveEmptyEntries); foreach (var item in arr) { if (item != string.Empty) { System.Diagnostics.Debug.WriteLine("接受到訊息" + item); JObject jobj = JObject.Parse(item); this.AsyncOperation.Post(OnReceiveDelegate, jobj); } } } Thread.Sleep(500); } } catch (Exception e) { this.AsyncOperation.Post(OnErrorDelegate, e); } } /// <summary> /// 心跳線程 /// </summary> private void HeartBeat() { try { while (true) { Thread.Sleep(8000); byte[] wb = System.Text.Encoding.UTF8.GetBytes("+h"); ns.Write(wb, 0, wb.Length); } } catch (Exception e) { this.AsyncOperation.Post(OnErrorDelegate, e); Thread.Sleep(5000); ReConnect(); } } /// <summary> /// 心跳失敗,則網路異常,重新串連 /// </summary> public void ReConnect() { if (readThread != null) { readThread.Abort(); } Connect(); } public void SendMsg(string msg) { byte[] wb = System.Text.Encoding.UTF8.GetBytes(msg); ns.Write(wb, 0, wb.Length); } public void SendMsg(JObject json) { SendMsg(json.ToString(Formatting.None)); } }}
使用方法
MyTcpClient client = MyTcpClient.getInstance();//保證回呼函數是在建立他的上下文執行(一般是UI線程)client.AsyncOperation = AsyncOperationManager.CreateOperation(null);client.Error += Client_Error; ;client.Receive += Client_Receive; ;client.Connected += Client_Connected;client.Connect();
參考
http://www.cnblogs.com/kex1n/p/6502002.html
https://www.codeproject.com/Articles/14265/The-NET-Framework-s-New-SynchronizationContext-Cla
http://www.cnblogs.com/leestar54/p/4591792.html
https://msdn.microsoft.com/zh-cn/library/vs/alm/system.componentmodel.asyncoperationmanager.createoperation(v=vs.85)
附件列表
C# TCPClient開發手記