C# 通过套接字传输数据
我想使用C# 通过套接字传输数据,c#,silverlight,sockets,concurrency,monitor,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 } [
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);
}
}
}
}
公共类连接{
私有易失性bool-readyToSend;
专用队列q;
私有对象缓冲监视器;
公共连接{
//初始化所有事物等并连接
}
[…]//与此问题无关的其他一些函数
专用void客户端已连接(SocketAsyncEventArgs args args){
//由线程A调用
[...]
readyToSend=true;
等待响应(args);
}
私有void WaitingForResponse(SocketAsyncEventArgs){
//由线程A调用
如果(q.Count==0){
锁(缓冲监视器){
Monitor.Wait(缓冲监视器);
}
}
如果(q.Count!=0){
字节[]数据;
锁(q){
data=q.Dequeue();
}
参数SetBuffer(0,数据长度);
args.ConnectSocket.SendAsync(args);
//将发送所有字节并调用WaitingForResponse
}否则{
//如果没有发生任何事情,将调用此函数。
}
}
内部void SendIfConnected(字节[]数据){
//由线程B调用
如果(readyToSend){
锁(q){
q、 排队(数据);
}
锁(缓冲监视器){
Monitor.pulsell(缓冲监视器);
}
}
}
}
此实现的问题很简单,当客户端连接时对readyToSend
的更改在第二个线程中不可见-第二个问题是,如果在SendIfConnected
函数中放置断点并手动将值更改为true,则监视器.Wait()
即使执行Monitor.pulsell,也不会返回
此外,我认为应该存在一些简单的解决方案来解决我最初的问题,而使用byte[]队列进行直播的整个想法并不是最好的。如果您能为我提供更好的指导,我将不胜感激。我忍不住觉得这里缺少了一些信息
-readyToSend实际上设置为true,但是线程B没有看到这个/Monitor.Pulsell在Monitor.Wait调用之前和之后被调用了多次。@Etan:愚蠢的问题,但是你确定在对象的同一实例上调用它吗?那么队列是否正确填充了?谢谢:P这就是问题所在。意外地,有两个实例,客户端总是连接到队列未填充的实例^^^如果您愿意,可以将您的评论作为答案重新发布,以便我可以接受。@Etan:我已更新了我的答案:)至少您发现了问题。