Skip to content

Instantly share code, notes, and snippets.

@ronnieoverby
Created February 25, 2016 22:43
Show Gist options
  • Save ronnieoverby/438034b19531e6272f98 to your computer and use it in GitHub Desktop.
Save ronnieoverby/438034b19531e6272f98 to your computer and use it in GitHub Desktop.
public static class SftpExtensions
{
/// <remarks>
/// unfortunately the ssh library doesn't expose a modern async api
/// that supports cancellation via CancellationToken
/// so we have to wrap the APM pattern with a TaskCompletionSource
/// </remarks>
public static Task UploadFileAsync(this SftpClient sftpClient, Stream input, string path, bool canOverride, Action<ulong> uploadCallback = null, CancellationToken cancellationToken = default(CancellationToken))
{
var tcs = new TaskCompletionSource<SftpUploadAsyncResult>();
var uploadResult = (SftpUploadAsyncResult)sftpClient.BeginUploadFile(input, path, canOverride, ar =>
{
var ar2 = (SftpUploadAsyncResult)ar;
try
{
ar2.EndInvoke();
if (ar2.IsUploadCanceled)
{
tcs.SetCanceled();
}
else if (ar2.IsCompleted)
{
tcs.SetResult(ar2);
}
}
catch (Exception ex)
{
tcs.SetException(ex);
}
}, null, uploadCallback);
cancellationToken.Register(() => uploadResult.IsUploadCanceled = true);
return tcs.Task;
}
}
@GonzoSpire
Copy link

GonzoSpire commented May 28, 2024

EndInvoke is not a public method anymore and it is internal. Is there any alternative or replacement? Thanks in advance.

You can use _client.EndUploadFile(ar2); instead.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment