【发布时间】:2011-03-28 10:32:29
【问题描述】:
我想使用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.Wait() 将永远不会返回,尽管 Monitor.PulseAll 已执行。
另外,我有点认为应该有一些简单的解决方案来解决我最初的问题,并且使用 byte[] 队列进行直播的整个想法并不是最好的。如果有任何更好的方向,我将不胜感激。
【问题讨论】:
标签: c# silverlight sockets concurrency monitor