/// <summary> /// 引发 DataReceived 事件。 /// </summary> /// <param name="e">包含事件数据的 <see cref="DataReceivedEventArgs"/>。</param> internal void FireDataReceived(DataReceivedEventArgs e) { if (this.DataReceived != null) { this.DataReceived(this, e); } }
internal PipeMessageContext(DataReceivedEventArgs eventArgs, MessageInfo messageInfo) : base(messageInfo) { if (eventArgs == null) { throw new ArgumentNullException("eventArgs"); } this.eventArgs = eventArgs; }
/// <summary> /// 从指定的 DataReceivedEventArgs 和 Message 创建 IMessageContext 的实例。 /// </summary> /// <param name="eventArgs">要从其创建 IMessageContext 实例的 DataReceivedEventArgs 对象。</param> /// <param name="messageInfo">要从其创建 IMessageContext 实例的 MessageInfo 对象。</param> /// <returns>MessageContext 实例。</returns> public static MessageContext CreateFrom(DataReceivedEventArgs eventArgs, MessageInfo messageInfo) { return new PipeMessageContext(eventArgs, messageInfo); }
void channel_DataReceived(object sender, DataReceivedEventArgs e) { this.owner.FireDataReceived(e); }
// 成功接收到数据后引发事件 private static void HandleReceivedData(object data) { Exception error = null; CallbackState state = data as CallbackState; if (state != null) { state.InvokeStacks.Add(new KeyValue<DateTime, string>() { Key = DateTime.Now, Value = Thread.CurrentThread.ManagedThreadId.ToString("#000") + " " + (Thread.CurrentThread.IsThreadPoolThread ? "true" : "false") + " HandleReceivedData" }); DataReceivedEventArgs eventArgs = null; try { eventArgs = new DataReceivedEventArgs(state); state.InvokeStacks.Add(new KeyValue<DateTime, string>() { Key = DateTime.Now, Value = "HandleReceivedData-FireDataReceived" }); state.Channel.FireDataReceived(eventArgs); // 通知调用方并返回结果 if (!eventArgs.IsReplied) { eventArgs.Reply(); } } catch (Exception err) { state.InvokeStacks.Add(new KeyValue<DateTime, string>() { Key = DateTime.Now, Value = "HandleReceivedData-Error:" + err.GetType().FullName }); // ReplyException 直接记录日志 if (err is ReplyException) { error = err; } else { // 其它错误,如果已经对调用方进行过应答,那么说明错误是在应答后发生的,仅记录日志 if (eventArgs.IsReplied) { error = err; } else // 未对调用方进行过应答,那么应将错误发送给调用方 { // 生成用于发送给调用方的错误对象 ReturnValue<object> retError = err is BusinessException ? ReturnValue<object>.GetBusinessError((BusinessException)err) : ( err is ArgumentException ? ReturnValue<object>.Get404Error(((ArgumentException)err).Message) : ReturnValue<object>.Get500Error(err) ); // 仅针对 404 或者 500 的错误在本地记录错误日志并发送给调用方,其它错误不记录日志,直接发送给调用方 if (retError.Code == 404 || retError.Code == 500) { error = err; } state.InvokeStacks.Add(new KeyValue<DateTime, string>() { Key = DateTime.Now, Value = "HandleReceivedData-WriteError" }); try { BinarySerializeHelper.Write(formatter, state.Channel.pipeStream, retError, true, state.Channel.sendTimeout); } catch { // 错误未能成功通知给发送方时,也应在本地记录错误日志,这时,发送方会一直等待直到出现超时错误,记录下此日志,方便查询 error = err; } } } } finally { state.InvokeStacks.Add(new KeyValue<DateTime, string>() { Key = DateTime.Now, Value = "HandleReceivedData-End" }); // 打印请求日志 int requestMilliseconds = (int)(state.InvokeStacks[state.InvokeStacks.Count - 1].Key - state.InvokeStacks[1].Key).TotalMilliseconds; if (error != null || eventArgs.ExtraError != null || requestMilliseconds > 3000 || XMS.Core.Container.LogService.IsDebugEnabled) { StringBuilder sb = new StringBuilder(128); if (error != null) { sb.Append("响应来自 AppInstanceId=" + state.Channel.Client.AppInstanceId + ", PipeName=" + state.Channel.Client.PipeName + " 的请求的过程中发生错误,详细错误信息为:"); sb.Append("\r\n"); sb.Append(error.GetFriendlyToString()); } else { if (requestMilliseconds > 3000 || XMS.Core.Container.LogService.IsDebugEnabled) { sb.Append("成功响应来自 AppInstanceId=" + state.Channel.Client.AppInstanceId + ", PipeName=" + state.Channel.Client.PipeName + " 的请求"); } } sb.Append("\r\n\t响应耗时:\t").Append(requestMilliseconds.ToString("#0.000")).Append(" ms"); sb.Append("\r\n\t调用步骤:\t"); for (int j = 0; j < state.InvokeStacks.Count; j++) { sb.Append("\r\n\t\t" + state.InvokeStacks[j].Key.ToString("HH:mm:ss.fff")).Append("\t").Append(state.InvokeStacks[j].Value); } // 记录 Reply 之后产生的附加错误 if (eventArgs.ExtraError != null) { sb.Append("\r\n但在成功响应请求后的本地处理过程中,发生以下错误:"); sb.Append("\r\n"); sb.Append(eventArgs.ExtraError.GetFriendlyToString()); } XMS.Core.Container.LogService.Warn(sb.ToString(), PipeConstants.LogCategory); } } } }