Har*_*lse 3 c# asynchronous task iasyncoperation
我可以访问 Connected Renci.SshNet.SftpClient,用它来获取 sftp 文件夹中的文件序列。用于此目的的函数是
Renci.SshNet.SftpClient.ListDirectory(string);
Run Code Online (Sandbox Code Playgroud)
由于目录中的文件数量巨大,这大约需要 7 秒。我希望能够使用 async/await 和取消令牌使我的 UI 保持响应。
如果 Renci.SshNet 有一个返回任务的 ListDirectoryAsync 函数,那么这将很容易:
async Task<IEnumerable<SftpFiles> GetFiles(SftpClient connectedSftpClient, CancellationToken token)
{
var listTask connectedSftpClient.ListDirectoryAsync();
while (!token.IsCancellatinRequested && !listTask.IsCompleted)
{
listTask.Wait(TimeSpan.FromSeconds(0.2);
}
token.ThrowIfCancellationRequested();
return await listTask;
}
Run Code Online (Sandbox Code Playgroud)
可惜 SftpClient 没有异步功能。以下代码有效,但在下载过程中不会取消:
public async Task<IEnumerable<SftpFile>> GetFilesAsync(string folderName, CancellationToken token)
{
token.ThrowIfCancellationRequested();
return await Task.Run(() => GetFiles(folderName), token);
}
Run Code Online (Sandbox Code Playgroud)
但是,SftpClient 确实具有使用以下函数的异步功能
public IAsyncResult BeginListDirectory(string path, AsyncCallback asyncCallback, object state, Action<int> listCallback = null);
Public IEnumerable<SftpFile> EndListDirectory(IAsyncResult asyncResult);
Run Code Online (Sandbox Code Playgroud)
在将 IAsyncResult 代码转换为新的异步和等待模式一文中描述了如何将 IAsyncResult 转换为等待。
但是我不知道如何处理 BeginListdirectory 中的所有参数以及将 EndListDirectory 放在哪里。任何人都可以将其转换为一个任务,我可以等待较短的超时来检查取消令牌?
看起来SftpClient
不遵循标准APM 模式:它listCallback
是 Begin 方法的额外参数。因此,我很确定你不能使用标准FromAsync
工厂方法。
但是,您可以使用 编写自己的TaskCompletionSource<T>
。有点尴尬,但可行:
public static Task<IEnumerable<SftpFile>> ListDirectoryAsync(this SftpClient @this, string path)
{
var tcs = new TaskCompletionSource<IEnumerable<SftpFile>>();
@this.BeginListDirectory(path, asyncResult =>
{
try
{
tcs.TrySetResult(@this.EndListDirectory(asyncResult));
}
catch (OperationCanceledException)
{
tcs.TrySetCanceled();
}
catch (Exception ex)
{
tcs.TrySetException(ex);
}
}, null);
return tcs.Task;
}
Run Code Online (Sandbox Code Playgroud)
(在浏览器中编写的代码,完全未经测试:)
我将其构建为扩展方法,这是我更喜欢的方法。这样您的消费代码就可以进行非常自然的connectedSftpClient.ListDirectoryAsync(path)
调用。
归档时间: |
|
查看次数: |
6154 次 |
最近记录: |