首页 新闻 会员 周边 捐助

关于task异步问题

0
悬赏园豆:20 [已解决问题] 解决于 2016-06-27 16:54

基于网络电话的软交换客户端信息监控实现,定义了一个同步发送命令的实现:

1、当系统接收到来自软交换的信息时,如果是命令响应,则将命令响应结果放到一个单独的队列

 

2、以异步的方式发送命令到软交换,然后监控命令队列是否有元素,有则返回该元素,否则循环等待。

 

现象:

1、当我向软交换(freeswitch)发送一般命令(如event、auth、log等)时,这个过程是OK的。

2、当我向软交换(freeswitch)发送api指令(如api originate、bgapi originate等)时,能接收到命令的响应信息,但是,task.Wait 却不终止等待。

 

现在,也不知道问题是软交换的问题还是task的问题,表面分析,都不应该有这样的现象。

 

代码如下:

        /// <summary>
        /// 执行外部命令
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        public CommandResult Command(ICommand command)
        {
            var task = SendCommandAsync(command);
            //发送event、log、auth等命令正常
            //发送api/bgapi指令,如api originate、bgapi originate时,这个wait一直等待
            task.Wait(); 
            return new CommandResult(task.Result);
        }

        /// <summary>
        /// 异步命令发送
        /// </summary>
        /// <param name="command"></param>
        /// <returns></returns>
        public async Task<ESLMessage> SendCommandAsync(ICommand command)
        {
            return await Task.Factory.StartNew(() =>
            {
                string message = command.ToString();
                _socket._messageProductor.SendMessage(message);
                while (!_disposed)
                {
                    if (this._commandQueue.Count > 0)
                    {
                        //无论是event、log、auth命令,还是api/bgapi命令,都正常的收到了命令响应,能执行到这里
                        return _commandQueue.Dequeue();
                    }
                    sleep();
                }
                return null;
            });
        }
问题补充:

发现新问题:

 

1、我的这个客户端的启动是在application_start时,启动后,把client静态式的存在于静态类中

2、调用是通过一个http请求,然后使用这个client去执行命令

3、无论是api/bgapi命令还是event、auth、log等命令,如果i在application_start(也就是client创建时)执行是没问题的,但是,通过http请求执行,则无论什么命令都有问题。

4、奇怪的是:要么不执行,要么不监听不到命令响应,为毛会使得task.Wait不终止?

519740105的主页 519740105 | 大侠五级 | 园豆:5810
提问于:2016-06-27 12:18
< >
分享
最佳答案
0

问题确认:

在asp.net中(别的系统未确认),每一个http请求,只能有一个线程运行。如果在一个请求里开启多个线程或异步任务,这些线程或异步任务,必须在主线程(http请求线程)返回后才会启动运行,这个也是最终导致我这个问题的原因,或者也是大家说的,在http请求中,要么同步,要么异步吧。

519740105 | 大侠五级 |园豆:5810 | 2016-06-27 16:53

asp.net没有这种限制,你说的这种情况估计为错误的使用task,导致异步方法等待上下文,而http请求的线程拿着上下文又等着task的result。

Daniel Cai | 园豆:10424 (专家六级) | 2016-06-29 13:35

@Daniel Cai: 问题也就如你所说,在http请求中,要异步就全异步,不要异步转同步。

519740105 | 园豆:5810 (大侠五级) | 2016-06-29 13:40
其他回答(1)
0

要异步就全异步,不要一半异步一半同步,最后很可能会死锁。

#1 ConfigureAwait(false)

#2 public async Task<CommandResult> CommandAsync(ICommand command)

...

收获园豆:20
Daniel Cai | 园豆:10424 (专家六级) | 2016-06-27 13:18

跟这个没关系,是另外一个原因导致的,再考虑新的实验方案

支持(0) 反对(0) 519740105 | 园豆:5810 (大侠五级) | 2016-06-27 13:20
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册