I have an issue about the server-client communication.
I googled around but I did not find a solution to this.
Right now I am using 32feet in order to get in touch 2 or more (till 7) BT clients to 1 BT server.
I need to broadcast a message from the server to every device in the same time, but I don't know how to do it.
The only way I figured out was to use the list of connection in order to send the message one per time, but it means a delay between each message sent (around 100 ms per device). Unfortunately it means to have a large delay on the last one.
Can someone please give me an advice on how to solve this problem?
Is there a way to broadcast the message to all devices in the same time?
If it can be helpfull, here there is the handle of connection and reading from devices.
Thanks for your help
private void btnStartServer_Click(object sender, EventArgs e)
{
btnStartClient.Enabled = false;
ConnectAsServer();
}
private void ConnectAsServer()
{
connessioniServer = new List<BluetoothClient>();
// thread handshake
Thread bluetoothConnectionControlThread = new Thread(new ThreadStart(ServerControlThread));
bluetoothConnectionControlThread.IsBackground = true;
bluetoothConnectionControlThread.Start();
// thread connessione
Thread bluetoothServerThread = new Thread(new ThreadStart(ServerConnectThread));
bluetoothServerThread.IsBackground = true;
bluetoothServerThread.Start();
}
private void ServerControlThread()
{
while (true)
{
foreach (BluetoothClient cc in connessioniServer)
{
if (!cc.Connected)
{
connessioniServer.Remove(cc);
break;
}
}
updateConnList();
Thread.Sleep(0);
}
}
Guid mUUID = new Guid("fc5ffc49-00e3-4c8b-9cf1-6b72aad1001a");
private void ServerConnectThread()
{
updateUI("server started");
BluetoothListener blueListener = new BluetoothListener(mUUID);
blueListener.Start();
while (true)
{
BluetoothClient conn = blueListener.AcceptBluetoothClient();
connessioniServer.Add(conn);
Thread appoggio = new Thread(new ParameterizedThreadStart(ThreadAscoltoClient));
appoggio.IsBackground = true;
appoggio.Start(conn);
updateUI(conn.RemoteMachineName+" has connected");
}
}
private void ThreadAscoltoClient(object obj)
{
BluetoothClient clientServer = (BluetoothClient)obj;
Stream streamServer = clientServer.GetStream();
streamServer.ReadTimeout=1000;
while (clientServer.Connected)
{
try
{
int bytesDaLeggere = clientServer.Available;
if (bytesDaLeggere > 0)
{
byte[] bytesLetti = new byte[bytesDaLeggere];
int byteLetti = 0;
while (bytesDaLeggere > 0)
{
int bytesDavveroLetti = streamServer.Read(bytesLetti, byteLetti, bytesDaLeggere);
bytesDaLeggere -= bytesDavveroLetti;
byteLetti += bytesDavveroLetti;
}
updateUI("message sent from "+clientServer.RemoteMachineName+": " + System.Text.Encoding.Default.GetString(bytesLetti));
}
}
catch { }
Thread.Sleep(0);
}
updateUI(clientServer.RemoteMachineName + " has gone");
}
private void updateUI(string message)
{
Func<int> del = delegate()
{
textBox1.AppendText(message + System.Environment.NewLine);
return 0;
};
Invoke(del);
}
private void updateConnList()
{
Func<int> del = delegate()
{
listaSensori.Items.Clear();
foreach (BluetoothClient d in connessioniServer)
{
listaSensori.Items.Add(d.RemoteMachineName);
}
return 0;
};
try
{
Invoke(del);
}
catch { }
}
I don't exactly understand how you do it right now (the italian names are not helping...) but maybe my solution can help you.
first of all, bluetooth classic does not support broadcast. so you have to deliver at one at a time.
i do connect to 7 serial port devices at a time, using 7 threads. then i tell every thread to send data. this is very close to same time, but of course not exactly.
let me know if that helps or if you need a code example.
Related
I currently have a partly synchronous (poor) implementation of UDP communication between my android App and a hardware which is broadcasting UDP packets. The App continuously polls the hardware for status information which then is used to update the UI. The App also has various screens, each requesting (only when user switches screens, not continuous) a different set of configuration information. The user can also make changes to the configurations and load them to the hardware. All this while, the status updates keeps running in the background. I am looking for a solution best suited to my scenario.
Here is what I have done so far (simplified to make it more readable)
void InitializeUDP()
{
udpClient = new UdpClient(15001);
sender = default(IPEndPoint);
ThreadPool.QueueUserWorkItem(o => UDP_StatusCommunicator());
udpClient.EnableBroadcast = true;
udpClient.Client.ReceiveTimeout = 500;
}
void UDP_StatusCommunicator()
{
while (true)
{
if (update_flag)
{
try
{
sent_packet = FrameGenerator(frame_Queue[screen], true); //Creates UDP Packet
//CheckQuery(sent_packet);
udpClient.Send(sent_packet, sent_packet.Length,"192.168.4.255", 15000);
received_packet = udpClient.Receive(ref sender);
//CheckResponse(received_packet);
RunOnUiThread(() =>
{
Update_UI(received_packet);
});
}
catch (SocketException e)
{
Console.Writeline("Socket Timeout: " + e);
}
}
Thread.Sleep(update_delay);
}
}
void UDPReadWrite(int screen, bool reading)
{
SelectFunctionQueue(screen); //Select the frames according to the screen selected
//CheckQueue(frame_Queue);
for (int i = 0; i < frame_Queue.Length; i++)
{
try
{
sent_packet = FrameGenerator(frame_Queue[i], reading);
//CheckQuery(sent_packet);
udpClient.Send(sent_packet, sent_packet.Length, "192.168.4.255", 15000);
received_packet = udpClient.Receive(ref sender);
//CheckResponse(received_packet);
if (sent_packet[2] == received_packet[2]) //Verify correct packet received
{
Update_UI(received_packet);
}
else
{
i--; //retry
}
}
catch (SocketException e)
{
Console.WriteLine("Socket Timeout: " e);
i--;
}
}
}
}
void Switch_Screen(int new_screen)
{
update_flag = false;
UDPReadWrite(new_screen, true)
update_flag = true;
}
void User_Config_Write(int screen, byte[] data)
{
update_flag = false;
Update_Payload(data);
UDPReadWrite(screen, false)
update_flag = true;
}
As you would have clearly noticed, this is a very flawed implementation. I keep running into issues like UI freeze, same socket usage being attempted by two threads simultaneously, stuck while waiting for packets. I have tried to use 'async await' but I am not implementing it correctly resulting in race conditions and what not. Any help would be appreciated
Update : After some research and testing I have found the below to be working satisfactorily. However, I would appreciate if someone could just verify whether it has been done correctly
UdpClient udpClient = new UdpClient();
UdpClient r_UdpClient = new UdpClient(15001);
IPEndPoint sender = default(IPEndPoint);
ManualResetEventSlim receive = new ManualResetEventSlim(true);
Task.Run(() => UDP_Transmit());
async void UDP_Transmit()
{
byte[] frame;
SelectFrameQueue(selector);
udpClient = new UdpClient(15001);
udpClient.EnableBroadcast = true;
udpClient.BeginReceive(new AsyncCallback(UDP_Receive), udpClient);
while (true)
{
for (int i = 0; i < frame_Queue.Length; i++)
{
frame = FrameGenerator(frame_Queue[i]); //Generates Frames
try
{
udpClient.Send(frame, frame.Length, "192.168.4.255", 15000);
}
catch (SocketException)
{
Log.Debug("Error", "Socket Exception");
}
if(!receive.Wait(10000)) //Receive Timeout
{
RunOnUiThread(() =>
{
ShowToast("Connection Timeout. Please check device");
});
};
await Task.Delay(update_delay); //To release pressure from H/W
receive.Reset();
}
}
}
void UDP_Receive(IAsyncResult result)
{
receive.Set();
r_UdpClient = result.AsyncState as UdpClient;
data = r_UdpClient.EndReceive(result, ref sender);
RunOnUiThread(() =>
{
Update_UI(data);
});
r_UdpClient.BeginReceive(new AsyncCallback(UDP_Receive), r_UdpClient);
}
I don't know what the intent of this code is:
void InitializeUDP()
{
udpClient = new UdpClient(15001);
sender = default(IPEndPoint);
ThreadPool.QueueUserWorkItem(o => UDP_StatusCommunicator());
udpClient.EnableBroadcast = true;
udpClient.Client.ReceiveTimeout = 500;
}
but it is not guaranteed that
udpClient.EnableBroadcast = true;
udpClient.Client.ReceiveTimeout = 500;
is executed before UDP_StatusCommunicator().
For client UIs like Xamarin Task.Run can be a good option over ThreadPool.QueueUserWorkItem.
You might want to take a look at Dataflow (Task Parallel Library), in particular to the ActionBlock to replace your queue.
You might also want to consider using Progress to report updates to the UI or using Reactive Extensions (Rx) to subscribe to updates from the UI.
I'm trying to port my code from an obsolete library called CastleMQ to NetMQ but I'm running into some problems.
I prefer to using polling with a timeout, for reliability - I just found that it worked best for me from trial and error compared to just sitting blocking the port indefinitely.
here is my CastleMQ code
public int ZeroPort;
private void ThreadProc()
{
var ctx = new Context();
try {
using (var repSocket = ctx.CreateSocket(SocketType.Rep))
{
string bindAddress = "tcp://*:"+ZeroPort;
repSocket.Bind(bindAddress);
print2("*** BINDING on {0} ***", bindAddress);
bool quit = false;
while (!quit) {
try {
var polling = new Polling(PollingEvents.RecvReady, repSocket);
polling.RecvReady += (socket) =>
{ // using socket.Recv() here is guaranted to return stuff
var msg = socket.Recv();
var msgStr = Encoding.UTF8.GetString(msg);
print2("[REP:{0}] {1}", bindAddress, msgStr);
switch (msgStr) {
case "positions": {
StringBuilder csv = new StringBuilder();
print2("csv: {0}", csv.ToString());
socket.Send(csv.ToString());
break;
}
default: {
socket.Send("Unrecognized Command: " + msgStr);
break;
}
}
};
polling.Poll(POLL_TIMEOUT_MS); // this returns once some socket event happens
} catch (Exception e) {
if (e is ThreadAbortException) {
quit = true;
print2("\n*** EXITED ***");
} else print2(e.ToString());
}
}
}
} catch (Exception e) {
print2(e.ToString());
} finally {
ctx.Dispose();
}
}
here is what I tried to do and then got lost with NetMQ
private void ThreadProc()
{
try {
string bindAddress = "#tcp://*:" + ZeroPort;
print2("*** BINDING on {0} ***", bindAddress);
using (var repSocket = new ResponseSocket(bindAddress))
using (var poller = new NetMQPoller { repSocket })
{
// bool quit = false;
// while (!quit)
// these event will be raised by the Poller
repSocket.ReceiveReady += (s, a) =>
{
// receive won't block as a message is ready
string msg = a.Socket.ReceiveString(); // defeinition for ReceiveString() can't be found
// send a response
a.Socket.Send("Response"); // it doesn't like "Response", do I need to wrap it in some object?
I'm especially confused as how to add a timeout so I can poll with a timeout in a loop the way my CastleMQ code does.
Any pointers would be much appreciated, thanks
i do have an embedded board (mini/tiny 210)
and i did try building an application which uses system.socket and system.socket.net in C# ( vs2005 - wince5 device application but i do have wince 6 on my device!! )
my purpose is to send and receive data bytes using Ethernet. for sending , well there is no problem but receive does need multitasking.
i should start a task so it can listen to the port if there is any data upcoming but once i add thread part to my code the whole program crashes (dose not do that in pc x64 core i5) but in embedded board it will crash.
if i eliminate multi tasking i might lose some data when networkstream.read is not online or when networkstream.read is online and i'm waiting for data,which ends in program will not respond up until the timeout. here is some of my codes . hope it helps.
this code does work :
private void button_connect_Click(object sender, EventArgs e)
{
try
{
//Thread TH = new Thread(new ThreadStart(con));
//TH.Start();
con();
}
catch
{
MessageBox.Show("THREAD ERROR");
}
}
public void con()
{
try
{
cli = null;
cli = new TcpClient();
cli.Connect(IPAddress.Parse(textBox_ip.Text),Convert.ToInt32(textBox_port.Text));
st = null;
st = cli.GetStream();
button_connect.Enabled = false;
button_Close.Enabled = false;
button_disconnect.Enabled = true;
statusBar1.Text = "Connected to server";
//Thread rec = new Thread(new ThreadStart(recf));
//rec.Start();
}
catch
{
MessageBox.Show("Connection faild","Error");
statusBar1.Text = "Faild to connect to server";
}
this code dose not work :
private void button_connect_Click(object sender, EventArgs e)
{
try
{
Thread TH = new Thread(new ThreadStart(con));
TH.Start();
//con();
}
catch
{
MessageBox.Show("THREAD ERROR");
}
}
public void con()
{
try
{
cli = null;
cli = new TcpClient();
cli.Connect(IPAddress.Parse(textBox_ip.Text),Convert.ToInt32(textBox_port.Text));
st = null;
st = cli.GetStream();
button_connect.Enabled = false;
button_Close.Enabled = false;
button_disconnect.Enabled = true;
statusBar1.Text = "Connected to server";
//Thread rec = new Thread(new ThreadStart(recf));
//rec.Start();
}
catch
{
MessageBox.Show("Connection faild","Error");
statusBar1.Text = "Faild to connect to server";
}
}
as you can see i'm getting this crash while just one of my task is in the code the second task has been commented
i appreciate your help in advance
The crash is probably caused by updating UI elements from a secondary thread.
The con method reads a textbox and updates several buttons as well as a status bar, and this should only happen on the main application thread.
To verify whether this is the issue, you could simply comment out the lines in the con method that access UI elements (copy the textbox value to a member string before starting the thread, or just hard-code the IP address) and re-run the application.
Then to actually fix the problem you'll have to look into Control.Invoke.
Ok, so I'm attempting to create a simple Chat application over TCP/IP for a group of friends of mine who play DnD online. Eventually I want to add more features, but for now I just want the chat to work!!
Here is the code I have for the Main Server
class MainServer
{
IPAddress m_address = IPAddress.Parse("127.0.0.1");
Int32 m_port = 5550;
public static Hashtable userNicknames = new Hashtable(50);
public static Hashtable connectionToNick = new Hashtable(50);
public MainServer()
{
TcpListener listener = new TcpListener(m_address, m_port);
Thread listenThread = new Thread(new ParameterizedThreadStart(StartListening));
listenThread.Start(listener);
Console.WriteLine("Listening for incoming connection requests...");
}
private void StartListening(Object listener)
{
TcpListener server = (TcpListener)listener;
ClientCommCenter commC;
server.Start();
while (true)
{
if (server.Pending())
{
TcpClient client = server.AcceptTcpClient();
Console.WriteLine("Client has connected...");
commC = new ClientCommCenter(client);
}
}
}
public static void SendSystemMessage(string msg)
{
StreamWriter writer;
TcpClient[] connectedClients = new TcpClient[MainServer.userNicknames.Count];
MainServer.userNicknames.Values.CopyTo(connectedClients, 0);
for (int ii = 0; ii < connectedClients.Length; ii++)
{
try
{
if (msg.Trim().Equals(String.Empty))
continue;
writer = new StreamWriter(connectedClients[ii].GetStream());
writer.WriteLine("Message from server: " + msg);
writer.Flush();
writer = null;
}
catch (Exception e)
{
MainServer.userNicknames.Remove(MainServer.connectionToNick[connectedClients[ii]]);
MainServer.connectionToNick.Remove(connectedClients[ii]);
}
}
}
public static void SendMessageToAll(string nickname, string msg)
{
StreamWriter writer;
TcpClient[] connectedClients = new TcpClient[MainServer.userNicknames.Count];
MainServer.userNicknames.Values.CopyTo(connectedClients, 0);
for (int ii = 0; ii < connectedClients.Length; ii++)
{
try
{
if (msg.Trim().Equals(String.Empty))
continue;
writer = new StreamWriter(connectedClients[ii].GetStream());
writer.WriteLine(nickname + ": " + msg);
writer.Flush();
writer = null;
}
catch (Exception e)
{
String user = (string)MainServer.connectionToNick[connectedClients[ii]];
SendSystemMessage("ATTENTION: " + user + " has disconnected from chat");
MainServer.userNicknames.Remove(user);
MainServer.connectionToNick.Remove(connectedClients[ii]);
}
}
}
}
Here is the main communication class, used separately by each client
class ClientCommCenter
{
TcpClient m_client;
StreamReader m_reader;
StreamWriter m_writer;
String m_nickname;
public ClientCommCenter(TcpClient client)
{
m_client = client;
Thread chatThread = new Thread(new ThreadStart(StartChat));
chatThread.Start();
}
private String GetNick()
{
m_writer.WriteLine("Enter a nickname to begin.");
m_writer.Flush();
return m_reader.ReadLine();
}
private void StartChat()
{
m_reader = new StreamReader(m_client.GetStream());
m_writer = new StreamWriter(m_client.GetStream());
m_writer.WriteLine("Connected to DnD Chat!!");
m_nickname = GetNick();
while (MainServer.userNicknames.Contains(m_nickname))
{
m_writer.WriteLine("ERROR!!! Username already in use");
m_nickname = GetNick();
}
MainServer.userNicknames.Add(m_nickname, m_client);
MainServer.connectionToNick.Add(m_client, m_nickname);
MainServer.SendSystemMessage("****** " + m_nickname + " ****** has joined the chat!");
m_writer.WriteLine("Now connected....");
m_writer.Flush();
Thread startChatting = new Thread(new ThreadStart(runChat));
startChatting.Start();
}
private void runChat()
{
try
{
String clientMessage = String.Empty;
while(true){
clientMessage = m_reader.ReadLine();
MainServer.SendMessageToAll(m_nickname, clientMessage);
}
}
catch(Exception e)
{
Console.WriteLine(e);
}
}
}
And finally, here is the code for the Client class:
public partial class MainForm : Form
{
[DllImport("kernel32.dll")]
private static extern void ExitProcess(int a);
TcpClient client;
StreamReader m_reader;
StreamWriter m_writer;
public MainForm()
{
InitializeComponent();
}
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
e.Cancel = false;
Application.Exit();
if (m_reader != null)
{
m_reader.Dispose();
}
ExitProcess(0);
}
private void MainForm_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Enter)
{
SendChat();
}
}
private void SendChat()
{
TextBox txtChat = (TextBox)chatEntry;
if (chatEntry.Lines.Length >= 1)
{
m_writer.WriteLine(txtChat.Text);
m_writer.Flush();
chatEntry.Text = String.Empty;
chatEntry.Lines = null;
}
}
private void RunChat()
{
StreamReader reader = new StreamReader(client.GetStream());
while (true)
{
Application.DoEvents();
if (this.InvokeRequired)
{
this.Invoke(new MethodInvoker( delegate{
RunChat();
}));
}
if (reader.Peek() > 0)
{
chatDisplay.AppendText(reader.ReadLine() + "\r\n");
chatDisplay.SelectionStart = chatDisplay.Text.Length;
}
}
}
private void toolstripConnectButton_Click(object sender, EventArgs e)
{
client = new TcpClient("127.0.0.1", 5550);
m_writer = new StreamWriter(client.GetStream());
m_reader = new StreamReader(client.GetStream());
Thread chatThread = new Thread(new ThreadStart(RunChat));
chatThread.Start();
while (true)
{
Application.DoEvents();
}
}
private void sendButton_Click(object sender, EventArgs e)
{
SendChat();
}
}
The problem that I am having with the above code is this: I can connect to the running server perfectly fine, and I am correctly prompted by the server that I have connected, and it then prompts me for a nickname.
I type the nickname into the text box and press send. After this occurs however, I stop receiving messages from the server all together. Literally nothing. I can even spam the connect button and it constantly shows up with the same two messages:
"Connected"
"Enter a nickname"
I have been trying to figure this out for close to 5 hours now, and I simply have no idea what is going on. I have a feeling it is something incredibly simple, as the solution is ALWAYS simple.
So, generous people of SO, can you figure out my problem? Why does my streamreader and streamwriter suddenly stop working?!?!?!
Two things:
First, skip the if (reader.Peek() > 0). Just call reader.ReadLine(); this will block until you have a line available. I am not sure why, but even after sending the message, Peek is returning -1, but ReadLine returns a line at that point, fixing the problem. Anyway, spinning around on Application.DoEvents() is not helping matters.
(Similarly, you can skip if (server.Pending())).
Second, your use of Invoke is faulty; you should not be "Invoking" RunChat() because that is the method that repeatedly polls the stream for new data. This means you will run the entire method on the UI thread, which is precisely what you want to avoid. The UI is busy pumping the Windows message queue. You should "Invoke" only the code that modifies the control's properties.
(I suspect that is why you found it necessary to use Application.DoEvents() anyway. You shouldn't need it if you are handling your threading correctly.)
(Also, the first thing you should do is to check InvokeRequired. As your method is now, you're creating a StreamReader that you can never use. There are other places where you do that, but that's off topic.)
Here are two suggestions:
private void RunChat()
{
StreamReader reader = new StreamReader(client.GetStream());
Delegate invoker = new Action<string>(AppendChatText);
while (true)
Invoke(invoker, reader.ReadLine());
}
or, to use the more classic "invoke" pattern:
private void RunChat()
{
StreamReader reader = new StreamReader(client.GetStream());
while (true)
AppendChatText(reader.ReadLine());
}
private void AppendChatText(string text)
{
if (this.InvokeRequired)
{
this.Invoke((Action<string>)AppendChatText, text);
return;
}
chatDisplay.AppendText(text + "\r\n");
chatDisplay.SelectionStart = chatDisplay.Text.Length;
}
The first has the advantage of creating only one Delegate object; the second creates a new one each time.
Finally, this is a very C# 1.2 approach to the problem. A more up-to-date approach would use async/await to avoid creating all those threads (not to mention System.Collections.Generic.Dictionary<,> instead of HashTable).
am trying to use Socket.Select in multi-threaded application , and I don't wanna use async socket , so here is my code :-
public class Server {
private TcpListener m_listener;
private IConnectionFactory m_factory;
private List<Socket> Sockets = new List<Socket>();
private ConcurrentDictionary<Socket, Connection> Clients = new ConcurrentDictionary<Socket, Connection>();
private ConcurrentDictionary<string, ConcurrentQueue<Socket>> Threads = new ConcurrentDictionary<string, ConcurrentQueue<Socket>>();
private int maxsockets = 0;
private object sync = new object();
public Server(string ip, int port, IConnectionFactory factory, int maxsockets) {
IPAddress ipa = IPAddress.Parse(ip);
TcpListener listener = new TcpListener(ipa, port);
this.maxsockets = maxsockets;
m_listener = listener;
m_factory = factory;
int threads = maxsockets <= 100 ? 1 : maxsockets / 100;
for (int i = 0; i < threads; i++) {
Thread th = new Thread(HandelSockets);
th.Name = i.ToString();
Threads.TryAdd(i.ToString(), new ConcurrentQueue<Socket>());
th.Start();
}
}
public void HandelSockets() {
ConcurrentQueue<Socket> queue = Threads[Thread.CurrentThread.Name];
Connection temp;
Socket sock;
while (true) {
try {
lock (sync) {
while (queue.TryDequeue(out sock)) {
if (Clients.TryGetValue(sock, out temp)) {
if (!temp.Alive) {
Sockets.Remove(sock);
Clients.TryRemove(sock, out temp);
} else {
temp.Receive();
Console.WriteLine("recved from thread num : " + Thread.CurrentThread.Name);
}
}
}
}
} catch { }
Thread.Sleep(1);
}
}
public void Run() {
m_listener.Start();
Console.WriteLine("listen started");
Sockets.Add(m_listener.Server);
while (true) {
try {
var temp_list = Sockets.ToList();
Socket.Select(temp_list, null, null, 1000);
foreach (Socket socket in temp_list) {
if (socket == m_listener.Server) {
var sock = m_listener.AcceptSocket();
Sockets.Add(sock);
Connection conn = m_factory.Create(sock);
Clients.TryAdd(sock, conn);
} else if (Clients.Count >= maxsockets) {
Clients[socket].OnMaxConnections();
break;
} else {
if (!Threads.Values.Any(x => x.Contains(socket))) {
var quque = Threads.Values.Where(x => !x.Contains(socket)).OrderBy(x => x.Count).First();
lock (sync) {
quque.Enqueue(socket);
}
}
break;
}
}
} catch {
}
}
}
}
problem is after a while one of the connected sockets will be delayed , one of the sockets will stop sending or receiving until one of the other sockets do so!, or it might take a few secs/minutes until it comeback to receive and send!
I have no clue why would that happen!? maybe the way I select a queue with? , I hope someone can point me to what could make that delay happen thanks.
lock (sync) {
while (queue.TryDequeue(out sock)) {
if (Clients.TryGetValue(sock, out temp)) {
if (!temp.Alive) {
Sockets.Remove(sock);
Clients.TryRemove(sock, out temp);
} else {
temp.Receive();
Console.WriteLine("recved from thread num : " + Thread.CurrentThread.Name);
}
}
}
}
I can't see your implementation of Connection.Receive but if it's a blocking call i.e. doesn't return until it has received data, then that thread would be holding onto a lock on the sync object which is causing your other threads to wait and therefore causing the delay.
Now that you know what is causing the problem you can make the necessary changes, however i highly recommend you use the async methods as it'll perform better and remove the need for locking entirely.
Edit: oh i just realised this is an old question