介紹
重新想象 Windows 8 Store Apps 之 後台任務
控制通道(ControlChannel)
示例
1、客戶端與服務端做 ControlChannel 通信的關鍵代碼
ControlChannelHelper/AppContext.cs
/* * 本例通過全局靜態變量來實現 app 與 task 的信息共享,以便後台任務可以獲取到 app 中的相關信息 * * 注: * 也可以通過 Windows.ApplicationModel.Core.CoreApplication.Properties 保存數據,以實現 app 與 task 的信息共享 */ using System.Collections.Concurrent; using Windows.Networking.Sockets; namespace ControlChannelHelper { public class AppContext { /// <summary> /// 從 ControlChannel 接收到的數據 /// </summary> public static ConcurrentQueue<string> MessageQueue = new ConcurrentQueue<string>(); /// <summary> /// 客戶端 socket /// </summary> public static StreamSocket ClientSocket; } }
ControlChannelHelper/SocketControlChannel.cs
/* * 實現一個 socket tcp 通信的 ControlChannel,client 將在此 ControlChannel 中實時接收數據 * * 注: * win8 client 和 socket server 不能部署在同一台機器上,否則會拋出異常:{參考的對象類型不支持嘗試的操作。 (異常來自 HRESULT:0x8007273D)} */ using System; using System.Threading.Tasks; using Windows.ApplicationModel.Background; using Windows.Foundation; using Windows.Networking; using Windows.Networking.Sockets; using Windows.Storage.Streams; namespace ControlChannelHelper { public class SocketControlChannel : IDisposable { // ControlChannel public ControlChannelTrigger Channel { get; set; } // 客戶端 socket private StreamSocket _socket; // 用於發送數據 private DataWriter _dataWriter; // 用於接收數據 private DataReader _dataReader; // 向服務端發送心跳的間隔時間,單位為分鐘,最小 15 分鐘 private uint _serverKeepAliveInterval = 15; // ControlChannel 的標識 private string _channelId = "myControlChannel"; public SocketControlChannel() { } public async Task<string> CreateChannel() { Dispose(); try { // 實例化一個 ControlChannel Channel = new ControlChannelTrigger(_channelId, _serverKeepAliveInterval, ControlChannelTriggerResourceType.RequestHardwareSlot); } catch (Exception ex) { Dispose(); return "控制通道創建失敗:" + ex.ToString(); } // 注冊用於向服務端 socket 發送心跳的後台任務,需要在 manifest 中做相關配置 var keepAliveBuilder = new BackgroundTaskBuilder(); keepAliveBuilder.Name = "myControlChannelKeepAlive"; // 注:如果走的是 WebSocket 協議,則系統已經為其內置了發送心跳的邏輯,此處直接指定為 Windows.Networking.Sockets.WebSocketKeepAlive 即可 keepAliveBuilder.TaskEntryPoint = "BackgroundTaskLib.ControlChannelKeepAlive"; keepAliveBuilder.SetTrigger(Channel.KeepAliveTrigger); // 到了發送心跳的間隔時間時則觸發,本例是 15 分鐘 keepAliveBuilder.Register(); // 注冊用於向用戶顯示通知的後台任務,需要在 manifest 中做相關配置 // 查看本欄目
/* * 用於向服務端 socket 發送心跳的後台任務 * * 注: * 如果走的是 WebSocket 協議,則系統已經為其內置了發送心跳的邏輯 * 只需要將 BackgroundTaskBuilder.TaskEntryPoint 設置為 Windows.Networking.Sockets.WebSocketKeepAlive 即可,而不需要再自定義此後台任務 */ using ControlChannelHelper; using System; using Windows.ApplicationModel.Background; using Windows.Networking.Sockets; using Windows.Storage.Streams; namespace BackgroundTaskLib { public sealed class ControlChannelKeepAlive : IBackgroundTask { public void Run(IBackgroundTaskInstance taskInstance) { if (taskInstance == null) return; // 獲取 ControlChannel // 查看本欄目