如下一個簡單的異步事件TCP客戶端實現html
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("localhost", 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)json