我想使用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()
也不会返回。
此外,我认为应该存在一些简单的解决方案,我的原始问题,并且使用一个字节[]队列直播的整个想法是不是最好的。我希望任何一点进入更好的方向。
- readyToSend实际上设置为true,但是线程B没有看到这个/ Monitor.PulseAll被多次调用,在Monitor.Wait调用之前和之后。 – Etan 2011-03-28 12:29:31
@Etan:愚蠢的问题,但你确定你在同一个对象实例上调用它吗?所以队列填充正确? – forsvarir 2011-03-28 12:34:35
谢谢:P这是问题所在。有意思的是,有两个实例,客户端总是连接到没有填充队列的客户端。^^如果你希望你可以重新发布你的评论作为答案,所以我可以接受它。 – Etan 2011-03-28 13:12:03