【发布时间】:2015-07-02 15:04:12
【问题描述】:
我可以访问 Connected Renci.SshNet.SftpClient,我用它来获取 sftp 文件夹中的文件序列。用于此的函数是
Renci.SshNet.SftpClient.ListDirectory(string);
由于目录中有大量文件,这大约需要 7 秒。我希望能够使用 async / await 和 cancelToken 保持我的 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;
}
唉,SftpClient 没有异步功能。以下代码有效,但在下载过程中不会取消:
public async Task<IEnumerable<SftpFile>> GetFilesAsync(string folderName, CancellationToken token)
{
token.ThrowIfCancellationRequested();
return await Task.Run(() => GetFiles(folderName), token);
}
不过,SftpClient 确实有一种使用函数的异步功能
public IAsyncResult BeginListDirectory(string path, AsyncCallback asyncCallback, object state, Action<int> listCallback = null);
Public IEnumerable<SftpFile> EndListDirectory(IAsyncResult asyncResult);
在文章Turn IAsyncResult code into the new async and await Pattern 中描述了如何将 IAsyncResult 转换为 await。
但是我不知道如何处理 BeginListdirectory 中的所有参数以及将 EndListDirectory 放在哪里。任何人都可以将其转换为一个任务,我可以等待很短的超时来检查取消令牌?
【问题讨论】:
标签: c# asynchronous task iasyncoperation