cosullivan / SmtpServer

A SMTP Server component written in C#
MIT License
675 stars 159 forks source link

SmtpServer.StartAsync cannot be cancelled. #186

Closed everttimmer1963 closed 1 year ago

everttimmer1963 commented 1 year ago

The following problem has been bugging me for a while.

Problem:

When I cancel the cancellationToken passed in with SmtpServer.StartAsync, it doesn't work as expected. The cancellation token should trigger the mailserver to terminate but it doesn't.

Cause:

Inside the ListenAsync task, the code enters a loop for accepting client connections. The loop will finish as soon as a combined token, that is created from the cancellationToken and internal shutDownToken, has it's IsCancellationRequested property set to false. Inside the loop, however, the cancellationToken is passed to endpointListener.GetPipeAsync instead of the combined token. Because of that, the combinedToken.IsCancellationRequested will never become false, and the code won't exit the loop.

Passing the combined token to endpointListener.GetPipeAsync will solve the problem.

Solution:

Replace cancellationToken by cancellationTokenSource.Tokem in the call to endppointListener.GetPipeAsync

Original Code: sessionContext.Pipe = await endpointListener.GetPipeAsync(sessionContext, cancellationToken).ConfigureAwait(false);

Fixed Code: sessionContext.Pipe = await endpointListener.GetPipeAsync(sessionContext, cancellationTokenSource.Token).ConfigureAwait(false);

nefarius commented 1 year ago

Made #192 for this case.

MarkFl12 commented 1 year ago

This PR looks good to me, and I think it'll fix #183 as well?

nefarius commented 1 year ago

Agreed! Hopefully the maintainer will see soon enough and merge 🙏

nefarius commented 1 year ago

For those who can't wait for an official update feel free to use my fork in the meantime.