Open alexandrius007 opened 4 years ago
We have the same case when the connection was closed immediately after opening. I guess the Progress implementation is to blame here:
using (var semaphore = new SemaphoreSlim(0, 1))
{
_jobPaused = new CancellationTokenSource();
_task = RunAsync(
new Progress<FtpServiceStatus>(
status =>
{
Status = status;
if (status == FtpServiceStatus.Running)
{
// ReSharper disable once AccessToDisposedClosure
semaphore.Release();
}
}));
await semaphore.WaitAsync(cancellationToken);
}
The Progress
uses SyncronizationContext.Post
to pass progress data and, theoretically, can be invoked after the semaphore will be disposed.
I have encountered the same issue. In my case, the problem occurred in conjunction with SslStreamConnectionAdapter
(explicit encryption).
This exception encountered before: Status must be Running, Stopped, or Paused, but was ReadyToRun.
System.InvalidOperationException:
at FubarDev.FtpServer.Networking.PausableFtpService+<StopAsync>d__19.MoveNext (FubarDev.FtpServer, Version=3.1.1.0, Culture=neutral, PublicKeyToken=null)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at FubarDev.FtpServer.ConnectionHandlers.SslStreamConnectionAdapter+<StopAsync>d__12.MoveNext (FubarDev.FtpServer, Version=3.1.1.0, Culture=neutral, PublicKeyToken=null)
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw (System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess (System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification (System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at FubarDev.FtpServer.FtpConnection+<StopAsync>d__61.MoveNext (FubarDev.FtpServer, Version=3.1.1.0, Culture=neutral, PublicKeyToken=null)
Immediately after that the same exception occured: The semaphore has been disposed.
System.ObjectDisposedException:
at System.Threading.SemaphoreSlim.CheckDispose (System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Threading.SemaphoreSlim.Release (System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at FubarDev.FtpServer.Networking.PausableFtpService+<>c__DisplayClass18_0.<StartAsync>b__0 (FubarDev.FtpServer, Version=3.1.1.0, Culture=neutral, PublicKeyToken=null)
at System.Progress`1.InvokeHandlers (System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
at System.Threading.ThreadPoolWorkQueue.Dispatch (System.Private.CoreLib, Version=5.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e)
This class extension helps to solve this problem:
internal class SemaphoreSlimExt : SemaphoreSlim
{
public SemaphoreSlimExt(int initialCount)
: base(initialCount)
{
}
public SemaphoreSlimExt(int initialCount, int maxCount)
: base(initialCount, maxCount)
{
}
public bool IsDisposed { get; internal set; }
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
IsDisposed = true;
}
}
and after
using (var semaphore = new SemaphoreSlimExt(0, 1))
{
_jobPaused = new CancellationTokenSource();
_task = RunAsync(
new Progress<FtpServiceStatus>(
status =>
{
Status = status;
if (status == FtpServiceStatus.Running && **!semaphore.IsDisposed**)
{
// ReSharper disable once AccessToDisposedClosure
semaphore?.Release();
}
}));
var res = semaphore.WaitAsync(cancellationToken);
res.Wait();
}
I get error
Could you help to understend the reason of the error? After error Program has critical error.