I listen to a port in a thread with the following method. While waiting in WaitOne
method, I stop the thread (I am doing IsCancellationRequested true) and I can not close the listener
object. Then I get an error when I want to listen to the same port.
Can I bind a listener object to a variable? If that variable is false, it will do an automatic shutdown.
I do not want to check that the thread is stopped with a separate thread and close the listener
.
public void StartListening(Connection connection)
{
// There are codes here..
try
{
listener.Bind(localEndPoint);
listener.Listen(2);
while (connection.CancellationTokenSource.IsCancellationRequested == false)
{
allDone.Reset();
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
allDone.WaitOne(); // While I'm waiting here, I'm making the 'IsCancellationRequested' variable true.
}
listener.Close();
}
catch (Exception e)
{
// There are codes here..
}
// There are codes here..
}
Note: The Connection
class is a class I created that contains theSystem.Threading.CancellationTokenSource CancellationTokenSource
property.
I don't know the precise structure of the connection
, but...
You could try waiting on two handles. (untested)
var handles = new EventWaitHandle[]
{
allDone,
connection.CancellationTokenSource.Token.WaitHandle
};
int index = EventWaitHandle.WaitAny(handles);
WaitAny returns the index of the waithandle whois set. So determine if you want to break your while or not.
Maybee something like:
public void StartListening(Connection connection)
{
// There are codes here..
try
{
listener.Bind(localEndPoint);
listener.Listen(2);
var handles = new EventWaitHandle[]
{
allDone,
connection.CancellationTokenSource.Token.WaitHandle
};
do
{
allDone.Reset();
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
}
while(EventWaitHandle.WaitAny(handles) == 0);
listener.Close();
}
catch (Exception e)
{
// There are codes here..
}
// There are codes here..
}
A way to cancel the listener. Can't make up something nicer at the moment. If someone has a better way... feel free ;-)
ManualResetEvent _listenerTerminated = new ManualResetEvent(false);
// <snip>
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
private void AcceptCallback(IAsyncResult ar)
{
// before calling EndAccept, check an event.
if(_listenerTerminated.WaitOne(0))
return;
var clientSocket = listener.EndAccept(asyncResult);
}
// <snip>
do
{
allDone.Reset();
listener.BeginAccept(new AsyncCallback(AcceptCallback), listener);
}
while(EventWaitHandle.WaitAny(handles) == 0);
_listenerTerminated.Set();
listener.Close();