首页 新闻 会员 周边 捐助

关于TASK与事件总线的同步

0
悬赏园豆:100 [已关闭问题] 关闭于 2017-08-04 02:09

一、需求:

1、NamedPipe 接收消息后触发消息事件,将事件放到事件总线

2、事件总线通过订阅事件来处理事件

3、事件存在处理完后返回值的可能,也存在不返回

4、对于有返回的事件处理,响应 CancellationTokenSource 的 Cancel

5、对于无返回的事件处理,通过 等待响应超时 的方式触发 Cancel

 

二、问题:

响应的结果在响应处理时能获得,返回时失败

 

三、代码:

1、事件发布与同步等待代码

        private string HandleRequestMessage(string message)
        {
            string result = null;
            CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(MESSAGE_PROCESS_RESPONSE_TIMEOUT);
            PipeMessageEvent @event = new PipeMessageEvent(this._pipeManager.Pipename, this.PipeConnection.NativeHandle, message);
            Task task = new Task((() => Task.Run(AsyncResponseWaiter)));
            @event.Reponsed += (s, e) => {
                result = @event.Result;
                PublishStateEvent($"[Event]Response Info: {result}");
                cancellationTokenSource.CancelAfter(SYNCHROUNOUSLY_TASK_DELAY_PERLOOP);
            };
            this.PublishEvent(@event);
            task.RunSynchronously();
            PublishStateEvent($"Response Info: [@event.Result]{@event.Result}, [result]{result}");
            return $"[@event.Result]{@event.Result}, [result]{result}";
            async Task AsyncResponseWaiter()
            {
                //Debug.WriteLine("begin AsyncResponseWaiter");
                await Task.Factory.StartNew(() => {
                    //Stopwatch watch = new Stopwatch();
                    //watch.Start();
                    while (!cancellationTokenSource.IsCancellationRequested)
                    {
                        Task.Delay(SYNCHROUNOUSLY_TASK_DELAY_PERLOOP);
                    }
                    //watch.Stop();
                    //Debug.WriteLine($"{cancellationTokenSource.IsCancellationRequested}, {watch.ElapsedMilliseconds}");
                }, cancellationTokenSource.Token);
                //Debug.WriteLine("end AsyncResponseWaiter");
            }

        }

2、事件发布处理代码

        public void Publish(IEvent @event)
        {
            if(@event == null)
            {
                return;
            }
            Task.Factory.StartNew(() => OnEventTask(@event));
        }

3、事件处理结果响应代码

        public string Result
        {
            get;
            private set;
        }

        /// <summary>
        /// 消息处理
        /// </summary>
        /// <param name="data"></param>
        public void Response(string data)
        {
            if(Interlocked.Decrement(ref this._responsedTimes) >= 0)
            {
                this.Result = data;
                this.Reponsed?.Invoke(this, EventArgs.Empty);
            }
        }

        /// <summary>
        /// 数据响应事件
        /// </summary>
        public event EventHandler Reponsed;
519740105的主页 519740105 | 大侠五级 | 园豆:5810
提问于:2017-08-03 22:11
< >
分享
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册