frontendTask.ContinueWith(result =>
{
OnPropertyChanged("FrontendLabel");
OnPropertyChanged("ToggleFrontend");
frontendServer.Dispose();
});
the frontendCancellor.Cancel(); take a couple of minutes to complete.
What is frontendCancellor? Can you explain a little more?
Sorry for the confusion.
private void __StartFrontend(object obj)
{
if (!Directory.Exists(FrontendRoot))
{
MessageBox.Show("frontend folder is missing.");
return;
}
var url = "http://localhost:8080/";
frontendServer = new WebServer(url);
frontendServer.RegisterModule(new StaticFilesModule(FrontendRoot));
frontendServer.Module<StaticFilesModule>().UseRamCache = true;
frontendServer.Module<StaticFilesModule>().DefaultExtension = ".html";
// We don't need to add the line below. The default document is always index.html.
//server.Module<Modules.StaticFilesWebModule>().DefaultDocument = "index.html";
frontendCancellor = new CancellationTokenSource();
frontendTask = frontendServer.RunAsync(frontendCancellor.Token);
OnPropertyChanged("FrontendLabel");
OnPropertyChanged("ToggleFrontend");
}
public void __StopFrontend(object obj)
{
frontendCancellor.Cancel();
frontendTask.Wait();
OnPropertyChanged("FrontendLabel");
OnPropertyChanged("ToggleFrontend");
}
Is the cancellation meant to be taking a while?
@hardywu what runtime are you using? .NET 46?
Yes.
I think I hit the same problem.. Trying to cancel server task takes forever, but happens immediately, if I visit the webservers address after cancel. My code looks like following:
System.Diagnostics.Debug.WriteLine("::1::");
serverToken.Cancel();
System.Diagnostics.Debug.WriteLine("::2::");
serverTask.Wait();
System.Diagnostics.Debug.WriteLine("::3::");
In console, I get the ::1:: and ::2:: lines, but ::3:: appears only after a long delay, or after visiting the servers address with browser. I think that the problem lies in this code:
https://github.com/unosquare/embedio/blob/master/src/Unosquare.Labs.EmbedIO/WebServer.cs
lines 331-333 ..
var clientSocket = await Listener.GetContextAsync().ConfigureAwait(false);
if (ct.IsCancellationRequested)
return;
If I understand this correctly the lister needs a new connection or timeout to continue to the cancel part of the loop. Which causes at least the issues I'm having
@McFizh can you test using the branch Issue121-CancellationDelay?
This new branch fixed my issue.. Thanks :)
Edit: although , just canceling task doesn't release the tcp port. I need to also call dispose method, but that in turn emits ObjectDisposedException
@hardywu can you verify?
@McFizh can you post a sample code?
@McFizh I was able to reproduce the issue, I committed some changes to stop the Listener.
With the latest changes the tcp port gets properly released and I can create/close server in a loop without problems. But with code shown below:
server = new WebServer("http://localhost:8080/", Unosquare.Labs.EmbedIO.Constants.RoutingStrategy.Regex);
serverToken = new CancellationTokenSource();
serverTask = server.RunAsync(serverToken.Token);
..............
System.Diagnostics.Debug.WriteLine("!1!");
serverToken.Cancel();
System.Diagnostics.Debug.WriteLine("!2!");
serverTask.Wait();
System.Diagnostics.Debug.WriteLine("!3!");
I get output like this:
!1!
!2!
Exception thrown: 'System.ObjectDisposedException' in System.dll
!3!
Edit.. I removed module from code example, as it didn't seem to have any effect
Do you have the stacktrace?
[External Code]
Unosquare.Labs.EmbedIO.dll!Unosquare.Net.EndPointListener.Accept(System.Net.Sockets.Socket socket, System.Net.Sockets.SocketAsyncEventArgs e, ref System.Net.Sockets.Socket accepted) Line 238
Unosquare.Labs.EmbedIO.dll!Unosquare.Net.EndPointListener.ProcessAccept(System.Net.Sockets.SocketAsyncEventArgs args) Line 270
Unosquare.Labs.EmbedIO.dll!Unosquare.Net.EndPointListener.OnAccept(object sender, System.Net.Sockets.SocketAsyncEventArgs e) Line 292
[External Code]
And the error itself is:
System.ObjectDisposedException
HResult=0x80131622
Message=Ei voi k盲ytt盲盲 poistettua objektia (translation: unable to used removed object).
Objektin nimi (translation: object name): System.Net.Sockets.Socket.
Source=System
StackTrace:
at System.Net.Sockets.Socket.AcceptAsync(SocketAsyncEventArgs e)
at Unosquare.Net.EndPointListener.Accept(Socket socket, SocketAsyncEventArgs e, Socket& accepted) in C:\Users\xyz\Source\Workspaces\embedio\src\Unosquare.Labs.EmbedIO\System.Net\EndPointListener.cs:line 238
My results:
The thread 0x96c4 has exited with code 0 (0x0).
!1!
!2!
!3!
Exception thrown: 'System.ObjectDisposedException' in System.dll
Exception thrown: 'System.ObjectDisposedException' in System.dll
But I'm not getting any exception to handle with Visual Studio. I think this is somehow expected because the EndPoint is shutting down and the socket is disposed.
I added "Unosquare.Labs.EmbedIO" project as a dependency solution to my project, and had to explicitly enable ObjectDisposedException exceptions in visual studio 2017 (it was disabled as default and hidden in submenus).
Oh and some times I also had the exception pop up after marker !3! .. might have something to do with threading (?) , but anyways the exception always happens at the same line
Yeah, but I don't see any practical solution here. Even if I catch ObjectDisposedException in Unosquare.Net.EndPointListener.Accept, the exception was raised and reported.
Any idea?
@McFizh ??
Most helpful comment
I think I hit the same problem.. Trying to cancel server task takes forever, but happens immediately, if I visit the webservers address after cancel. My code looks like following:
In console, I get the ::1:: and ::2:: lines, but ::3:: appears only after a long delay, or after visiting the servers address with browser. I think that the problem lies in this code:
https://github.com/unosquare/embedio/blob/master/src/Unosquare.Labs.EmbedIO/WebServer.cs
lines 331-333 ..
If I understand this correctly the lister needs a new connection or timeout to continue to the cancel part of the loop. Which causes at least the issues I'm having