c# - 通过套接字流式传输数据

标签 c# silverlight sockets concurrency monitor

我想使用 Socket 将实时数据从一台服务器广播到多个客户端。
但是,我在当前实现中遇到了并发问题。

public class Connection {
    private volatile bool readyToSend;
    private Queue<byte[]> q;
    private object bufferMonitor;

    public Connection { 
        // initialize all things etc and connect
    }

    [...] // some other functions which are irrelevant for this problem

    private void ClientConnected (SocketAsyncEventArgs args) {
        // called by Thread A
        [...]
        readyToSend = true;
        WaitingForResponse(args);
    }

    private void WaitingForResponse (SocketAsyncEventArgs) {
        // called by Thread A
        if (q.Count == 0) {
            lock (bufferMonitor) {
                Monitor.Wait(bufferMonitor);
            }
        }
        if (q.Count != 0) {
            byte[] data;
            lock (q) {
                data = q.Dequeue();
            }
            args.SetBuffer(0, data.Length);
            args.ConnectSocket.SendAsync(args);
            // Will send all bytes and recall to WaitingForResponse afterwards
        } else {
            // Will recall this function if nothing happened.
        }
    }

    internal void SendIfConnected (byte[] data) {
        // called by Thread B
        if (readyToSend) {
            lock (q) {
                q.Enqueue(data);
            }
            lock (bufferMonitor) {
                Monitor.PulseAll(bufferMonitor);
            }
        }
    }        
}

此实现的问题很简单,当客户端连接时对 readyToSend 的更改在第二个线程中不可见 - 第二个问题是,如果您在 SendIfConnected 函数并手动将值更改为 true,即使执行了 Monitor.PulseAll,Monitor.Wait() 也不会返回。

此外,我认为应该存在一些简单的解决方案来解决我最初的问题,并且使用 byte[] 队列进行直播的整个想法并不是最好的。如果能指出更好的方向,我将不胜感激。

最佳答案

我不禁觉得这里缺少一些信息。

  1. 在给出的代码中,bufferMonitor 从未被初始化。如果它没有在您未包含的某些代码中完成,那么我预计锁定调用会失败。

  2. 您似乎是在说 readyToSend 从未设置为 true。从提供的代码来看,这表明永远不会调用 clientConnected 方法,或者 [...] 在执行该方法的那一行之前抛出/返回。您确定正在调用 clientConnected 吗?

  3. '在此处放置一个断点'指的是哪里?

  4. 据我了解,Monitor.Wait(假设已创建锁定对象)只有在执行 Monitor.PulseAll 时才会返回,线程 A 进入等待状态后。您确定这是正在发生的事件的顺序吗?如果脉冲发生在等待被调用之前,线程将不会被唤醒。

  5. 愚蠢的问题,但你确定你在对象的同一个实例上调用它吗?那么队列是否正确填充?

关于c# - 通过套接字流式传输数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5457697/

相关文章:

c - select() 错误 : invalid argument

c# - FluentNHibernate 查询多对多关系对象

c# - ASP.NET Core 3 实现 IAuthorizationPolicyProvider

silverlight - 在 silverlight 中打开响应流

silverlight - Windows Phone - OnNavigatingFrom - 问题

c# - 自定义 MediaStreamSource 和 MediaElement.Naturalduration 属性

python - python中的Errno 10061,我不知道该怎么办

c# - 继承一个没有任何构造函数的抽象类

c# - StringFormat 在设计器中显示错误,但在编译后不显示

c++ - 从套接字在线程中接收消息