I use HttpListener class for simple multitheading HTTP server for Long Polling actions. I use AutoResetEvents and WaitHandle.WaitAny for signal messaging between threads. Application works fine on .NET 4.5. But we have some problem with multithreading after porting application on Mono (version 3.2.8 (Debian 3.2.8+dfsg-4ubuntu1)).
We expected when second HTTP request is received by server handling of first HTTP request should be finish. And so on. But in Mono handling of first request finish only by timeout.
The simplified code of my application is below.
class Program
{
private static AutoResetEvent autoEvent = new AutoResetEvent(false);
private static AutoResetEvent autoEvent2 = new AutoResetEvent(false);
public static void Main()
{
HttpListener listener = new HttpListener();
listener.Prefixes.Add("http://*:2999/");
listener.Start();
Console.WriteLine("Listening...");
BeginGetContext(listener);
Console.ReadLine();
}
public static void BeginGetContext(HttpListener listener)
{
Console.WriteLine("BeginGetContext...");
while (listener.IsListening)
{
var asyncResult = listener.BeginGetContext(ListenerCallback, listener);
asyncResult.AsyncWaitHandle.WaitOne();
}
}
public static void ListenerCallback(IAsyncResult result)
{
Console.WriteLine("ListenerCallback...");
autoEvent.Set();
autoEvent.Reset();
HttpListener listener = (HttpListener)result.AsyncState;
HttpListenerContext context = listener.EndGetContext(result);
// some code
//...
int res = WaitHandleNext();
if (res == 0 || res == 1)
{
// Never get this line
Console.WriteLine("Done...");
}
else if (res == WaitHandle.WaitTimeout)
{
// Always here
Console.WriteLine("Done by timeout");
}
}
private static int WaitHandleNext()
{
Console.WriteLine("WaitHandleNext...");
int waitResult = WaitHandle.WaitAny(new[] { autoEvent, autoEvent2 }, TimeSpan.FromSeconds(30), false);
return waitResult;
}
}
If I put Thread.Sleep(10) between autoEvent.Set and autoEvent.Reset I get expected behaviour but not always.
autoEvent.Set();
Thread.Sleep(10);
autoEvent.Reset();
I don't know it is expected behaviour of Mono, bug in Mono or my application bug.
How can I reach behaviour of my application on Mono such on .Net? Any workarounds or other help would be great.
Related
I've written a tcp socket prgram that working with sockets asyncoronously.
This is some part of my code:
public void main()
{
var e = new SocketAsyncEventArgs();
e.Completed += new EventHandler<SocketAsyncEventArgs>(e_Completed);
Task.Factory.StartNew(() =>
{
allDone.Reset();
mySocket.AcceptAsync(e);
allDone.WaitOne();
});
}
public void e_Completed(object sender, SocketAsyncEventArgs e)
{
var socket = (Socket)sender;
ThreadPool.QueueUserWorkItem(HandleTcpRequest, e.AcceptSocket);
e.AcceptSocket = null;
socket.AcceptAsync(e);
}
public void HandleTcpRequest(object state)
{
var mySocket = (Socket)state;
try
{
//do some codes and work with mySocket
}
catch (Exception ex)
{
}
finally
{
mySocket.Close();
mySocket.Dispose();
}
}
I've seen lots of \device\afd in process explorer in my process. I've read and searched a lot about this and found that it is related to the Ancillary Function Driver and the Transport Driver Interface. How can I resolve this handle leak?
==========> edited my code:
Edited to accept only 10 sockets in sync way.
Feel that program is more faster, but when push my finger on Ctrl+F5, find that
there are more than 10 \device\afd in process explorer and when continuing too push, see more \device\afd, but lower that above code.
mySocket.Listen(10);
while (true)
{
using (Socket so = mySocket.Accept())
{
HandleTcpRequest(so);
}
}
I have the following C# code:
using System.Collections.Generic;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace CTCServer
{
class Server
{
//Stores the IP Adress the server listens on
private IPAddress ip;
//Stores the port the server listens on
private int port;
//Stores the counter of connected clients. *Note* The counter only gets increased, it acts as "id"
private int clientCount = 0;
//Defines if the server is running. When chaning to false the server will stop and disconnect all clients.
private bool running = true;
//Stores all connected clients.
public List<Client> clients = new List<Client>();
//Event to pass recived data to the main class
public delegate void GotDataFromCTCHandler(object sender, string msg);
public event GotDataFromCTCHandler GotDataFromCTC;
//Constructor for Server. If autoStart is true, the server will automaticly start listening.
public Server(IPAddress ip, int port, bool autoStart = false)
{
this.ip = ip;
this.port = port;
if (autoStart)
this.Run();
}
//Starts the server.
public void Run()
{
//Run in new thread. Otherwise the whole application would be blocked
new Thread(() =>
{
//Init TcpListener
TcpListener listener = new TcpListener(this.ip, this.port);
//Start listener
listener.Start();
//While the server should run
while (running)
{
//Check if someone wants to connect
if (listener.Pending())
{
//Client connection incoming. Accept, setup data incoming event and add to client list
Client client = new Client(listener.AcceptTcpClient(), this.clientCount);
//Declare event
client.internalGotDataFromCTC += GotDataFromClient;
//Add to list
clients.Add(client);
//Increase client count
this.clientCount++;
}
else
{
//No new connections. Sleep a little to prevent CPU from going to 100%
Thread.Sleep(100);
}
}
//When we land here running were set to false or another problem occured. Stop server and disconnect all.
Stop();
}).Start(); //Start thread. Lambda \(o.o)/
}
//Fires event for the user
private void GotDataFromClient(object sender, string data)
{
//Data gets passed to parent class
GotDataFromCTC(sender, data);
}
//Send string "data" to all clients in list "clients"
public void SendToAll(string data)
{
//Call send method on every client. Lambda \(o.o)/
this.clients.ForEach(client => client.Send(data));
}
//Stop server
public void Stop()
{
//Exit listening loop
this.running = false;
//Disconnect every client in list "client". Lambda \(o.o)/
this.clients.ForEach(client => client.Close());
//Clear clients.
this.clients.Clear();
}
}
}
Should run not be in a loop to create new threads?
If the first question is not true, and the lambda expression already creates new thread, at which point is new thread created? and where is the logic to decide it?
new Thread( will create the new thread. The lambda is executed on the thread. Run should not be in a loop. Because it will create many threads.
and the lambda expression already creates new thread, no it will be used as the thread method.
The only problem is, that you don't have a reference to the thread, so you cannot wait until it is terminated.
Also you're using a bool running for the while loop. You'd better use a ManualResetEvent for it.
I use this as standard thread setup:
// signal for terminating the thread.
private ManualResetEvent _terminating = new ManualResetEvent(false);
private Thread _thread;
public void Start()
{
ManualResetEvent threadStarted = new ManualResetEvent(false);
_thread = new Thread(() =>
{
threadStarted.Set();
while(!_terminating.WaitOne(0))
{
// do your thing here.
}
});
_thread.Start();
threadStarted.WaitOne();
}
public void Dispose()
{
_terminating.Set();
_thread.Join();
}
One remark here is: Should you use Threaded clients or async sockets.
Threaded clients: client count <= 10
async sockets: client count > 10
The problem with a server is, that your not in charge of how many clients are connecting.
Some pseudo code how to setup your tcp-server and running threads for each client.
public class Server
{
// signal for terminating the thread.
private ManualResetEvent _terminating = new ManualResetEvent(false);
private List<ClientHandler> _clients = new List<ClientHandler>();
public void Start()
{
ManualResetEvent threadStarted = new ManualResetEvent(false);
_thread = new Thread(() =>
{
threadStarted.Set();
// create listener.....
while(!_terminating.WaitOne(0))
{
// do your thing here.
// accept socket
var socket = _listenerSocket.Accept();
ClientHandler handler = new ClientHandler(socket);
_clients.Add(handler);
}
});
_thread.Start();
threadStarted.WaitOne();
}
public void Dispose()
{
_terminating.Set();
_thread.Join();
}
}
public class ClientHandler
{
// signal for terminating the thread.
private ManualResetEvent _terminating = new ManualResetEvent(false);
public ClientHandler(Socket socket)
{
ManualResetEvent threadStarted = new ManualResetEvent(false);
_thread = new Thread(() =>
{
threadStarted.Set();
while(!_terminating.WaitOne(0))
{
// do your thing here.
// accept socket
var bytesReaded = socket.Read(.....);
// handle data....
}
});
_thread.Start();
threadStarted.WaitOne();
}
public void Dispose()
{
_terminating.Set();
_thread.Join();
}
}
I'm trying to create two client threads which are connected to a server. When there are two connections (Two entries in the threadsArray), I want the start to be announced. The code is never hitting the threadRequest.annouceStart() call however.
Through debugging I have determined that the first thread that is created is being stopped while the server is listening for another connection in the form of the second client. Is it this "freeze" as the server hangs waiting for another connection that is stopping the first thread?
static void Main(string[] args)
{
runServer();
}
static void runServer()
{
TcpListener listener;
Socket connection;
Handler threadRequest;
string defaultName = "";
int defaultScore = 0;
int i = 0;
Thread[] threadsArray = new Thread[2];
try
{
listener = new TcpListener(IPAddress.Any, 43);
listener.Start();
Console.WriteLine("Quiz Server launched");
Console.WriteLine("A default user has been created for testing purposes");
while(true) //main game loop
{
connection = listener.AcceptSocket();
threadRequest = new Handler();
threadsArray[i] = new Thread(() => threadRequest.clientInteraction(connection, teamInformation));
threadsArray[i].Name = "Team" + (i + 1);
threadsArray[i].Start();
i++;
if (threadsArray[1] != null)
{
if (threadsArray[1].ThreadState == ThreadState.Running
&& threadsArray[0].ThreadState == ThreadState.Running)
{
foreach (Thread thread in threadsArray)
{
threadRequest.announceStart(connection, teamInformation);
}
}
}
}
}
catch (Exception e)
{
Console.WriteLine("Exception: " + e.ToString());
Console.ReadKey();
}
}
edit: added Handler class definition.
class Handler {
public static string interactionType;
public static string pTeamName;
public static string pAnswer;
public void announceStart(Socket connection, ConcurrentDictionary<string, int> teamInformation)...
public void clientInteraction(Socket connection, ConcurrentDictionary<string, int> teamInformation)...
public static void parseStrings(StreamReader sr, string recievedLine, out string pTeamName,
out string pAnswer)...
static void findInteractionType(out string interactionType, string clientString)...
}
Credit to Andrey Polyakov in comments.
"Thread stops if executing method returns. You should run infinite loop in such method for avoid thread termination" in regards to the clientInteraction() method.
I'm trying to create a simple game using the XNA Framework. I'm starting to implement multiplayer over LAN. Everything has been going well but now I'm running into a problem with UDPClient.Receive.
When the server is running, it is supposed to have two listeners(using UDPClient.Receive), on different ports. One listener is waiting for any incoming connection requests for people who want to join the game and respond accordingly. The other listens for constant updates on the player's positions so it can keep all players' views synchronised. The problem is that I don't know how to code in the first listener.
When the listener for connection request starts, all the code freezes, and it doesn't start until that listener will receive something. How would I code it so it is just running in the background?
Here is my code for the connection listener:
public class Connect
{
public static void WaitForConnections()
{
UdpClient udpc2 = new UdpClient(2054);
IPEndPoint ep = null;
Random rnd = new Random();
Console.WriteLine("Waiting for connections...");
byte[] joinrequest = udpc2.Receive(ref ep);
if (Encoding.ASCII.GetString(joinrequest) == "join")
{
Console.WriteLine("Attempting to join");
if (Server.ConnectedPlayers.Count < Server.MaxPlayers)
{
byte[] newShooter = DataControls.ClassToByteArray(new ShooterObject(Server.ConnectedPlayers.Count + 1, new Vector2(((Server.ConnectedPlayers.Count + 1) * 100) + 22, 70), new byte[3] { (byte)rnd.Next(255), (byte)rnd.Next(255), (byte)rnd.Next(255) }));
udpc2.Send(newShooter, newShooter.Length, ep);
Console.WriteLine("Joined successfully");
}
else
{
byte[] error = Encoding.ASCII.GetBytes("full");
udpc2.Send(error, error.Length, ep);
Console.WriteLine("Too many players");
}
}
}
}
You need to use a background worker thread or equivalent (look at Task and threads generally) but to help you get going in basic full example:
using System;
using System.ComponentModel;
using System.Threading;
namespace ConsoleApplication1
{
internal class Program
{
private static void Main()
{
// Create our listener and start listening...
var sammpleListener = new SampleListener();
sammpleListener.StartListening();
// Run forever...
Console.WriteLine("Waiting for players to join...");
Console.WriteLine("Press Ctrl+C to stop!");
for (var counter = 1;; counter++)
{
Console.WriteLine("Main thread working: {0}...", counter);
Thread.Sleep(200);
}
}
internal class SampleListener
{
private readonly BackgroundWorker _udpWaitForPlayer;
public SampleListener()
{
_udpWaitForPlayer = new BackgroundWorker();
_udpWaitForPlayer.DoWork += _udpWaitForPlayer_DoWork;
}
public void StartListening()
{
_udpWaitForPlayer.RunWorkerAsync();
}
private void _udpWaitForPlayer_DoWork(object sender, DoWorkEventArgs e)
{
const int junkSample = 10;
for (var i = 1; i <= junkSample; i++)
{
// Notice how this doesn't make the main thread sleep / hang...
Console.WriteLine("Background worker working: {0} of {1}...", i, junkSample);
Thread.Sleep(1000);
}
Console.WriteLine("Background worker: Finished!");
}
}
}
}
I want run a thread continuously. This thread would poll and check for card status. Here is a sample implementation:
static void Main(string[] args)
{
var _cancelationTokenSource = new CancellationTokenSource();
new Task(() => chkRequestTask(_cancelationTokenSource), _cancelationTokenSource.Token, TaskCreationOptions.LongRunning).Start();
while (true)
{
}
}
static bool chkRequestTask(CancellationTokenSource _cancellationTokenSource)
{
bool noRequest = false;
while (!_cancellationTokenSource.Token.IsCancellationRequested)
{
var RequestTask = Task.Factory.StartNew(() => noRequest = chkRequestTask(_cancellationTokenSource), _cancellationTokenSource.Token);
if (noRequest)
{
_cancellationTokenSource.Token.WaitHandle.WaitOne(15000);
Console.WriteLine("Waiting for 15Seconds");
}
else
{
Console.WriteLine("Checking the card");
}
}
return noRequest;
}
What I want to achieve here is chkRequestTask should be run on a separate thread. This would continously poll the status of the card. For this sample I'm simply doing : Console.WriteLine("Checking the card");.
Once it checks the status of the card it should sleep for 15secs for this sample only (in general it should check every 50ms, but for testing purposes I have kept 15secs).
But in the above sample it's not sleeping it's simply giving me Checking the card continuously. It's not sleeping at all for 15secs. What is wrong with this code ?
You're calling chkRequestTask recursively using Task.Factory.StartNew which you don't need at all.
It's not clear why you need to poll the status, better idea is to check any event or callback or WaitHandle provided by the card API you're talking about. That should keep you away from the pain.
If at all you believe polling is the only option you've left with, you can do it as follows.
static async Task ChkRequestTask(CancellationToken token)
{
while (true)
{
token.ThrowIfCancellationRequested();
Console.WriteLine("Checking the card");
bool status = PollTheCardForStatus();
if(!status)
break;
await Task.Delay(15 * 1000, token);//Adjust the delay as you wish
}
}
Else where in code, if possible await the call, If not then attach a continuation or use blocking task.Wait.
await ChkRequestTask(token);
This method doesn't need to return bool as you're returning from the method only when it is false, it is safe to assume the status is false when the Task returned from ChkRequestTask completes, which means poll returned false or the CancellationToken is cancelled, in which case you'll get TaskCanceledException
This is how I have done this. It seems to be working properly. As it's a background thread it would exit when the application exits. Could someone advise If this is the right way to do it.
private void Form1_Load(object sender, EventArgs e)
{
m_dev = DASK.Register_Card(DASK.PCI_7250, 0);
if (m_dev < 0)
{
MessageBox.Show("Register_Card error!");
}
FunctionToCall();
}
private void FunctionToCall()
{
short ret;
uint int_value;
var thread = new Thread(() =>
{
while (true)
{
ret = DASK.DI_ReadPort((ushort)m_dev, 0, out int_value);
if (ret < 0)
{
MessageBox.Show("D2K_DI_ReadPort error!");
return;
}
if (int_value > 0)
{
textBox2.Invoke(new UpdateText(DisplayText), Convert.ToInt32(int_value));
}
Thread.Sleep(500);
}
});
thread.Start();
thread.IsBackground = true;
}
private void DisplayText(int i)
{
textBox2.Text = i.ToString();
}