c# - 有没有异步方式连接到SFTP服务器?

标签 c# asynchronous sftp

我正在开发一个 API,它接收消息并将其以 .json 格式上传到 SFTP 服务器。但是,连接时间太长,SFTP 连接需要 1 秒多,这太多了。 我想知道是否有什么方法可以连接到服务器并发送文件而无需等待这么长时间。

我想过保存文件,回复客户端,然后用这种方法上传文件:

public async Task Upload(string localPath, string remotePath)
{
    await Task.Run(() =>
    {
        // upload code here
    });
}

但是,如果上传过程中出现异常,API可能已经向客户端返回OK,无法通知客户端上传失败。

这是我当前用于上传文件的现有代码:

public void Upload(string localPath, string remotePath)
{
    try
    {
        using (var sftp = new SftpClient(...))
            {
                sftp.Connect(); // Very slow
                sftp.UploadFile(...);
                sftp.Disconnect();
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, "Error Upload SFTPHandler");
    }
}

有人可以建议一个解决方案来连接到 SFTP 服务器并发送文件而无需等待这么长时间吗?

最佳答案

您可以存储上传状态,并单独检查是否已上传。例如,您可以将状态缓存在 ConcurrentDictionary 中。然后,客户端可以定期轮询上传状态。

假设您使用的是 SSH.Net 客户端,您还可以使用其异步方法。

static ConcurrentDictionary<string, bool> _statuses = new();

[HttpPost]
public async Task UploadFile(string localPath, string remotePath)
{
    _statuses[remotePath] = false;
    Task.Run(() => Upload(localPath, remotePath));
}

private async Task Upload(string localPath, string remotePath)
{
    try
    {
        using var sftp = new SftpClient(...);
        sftp.ConnectAsync();
        await TaskFactory.FromAsync(
            (input, path, asyncCallback, state) =>
                sftp.BeginUploadFile(input, path, asyncCallback),
            sftp.EndUploadFile,
            ..., // some filestream
            remotePath,
            null);
        _statuses[remotePath] = true;
        sftp.Disconnect();
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, "Error Upload SFTPHandler");
    }
}


[HttpPost]
public async Task<bool> IsUploaded(string remotePath)
{
    if (!_statuses.TryGetValue(remotePath, out var value))
    {
        // IIS was restarted.
        // check SFTP for finished upload.
        _statuses.Add(someStatus);
    }
    return value;
}

您可能需要考虑某种在 IIS 服务器重新启动时缓存状态的方法。

关于c# - 有没有异步方式连接到SFTP服务器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75745090/

相关文章:

c# - 使用C#表单应用程序和youtube-v3-api在YouTube实时流聊天中插入评论

c# - 在 C# 插件中调用 Dynamics Web API

javascript - 如何处理异步获取的数据?

batch-file - WinSCP "Too many parameters for command ' 打开'。”错误

shell - cd命令失败时如何退出SFTP

c# - 集合中集合的 Linq where 子句

c# - 序言异常中不允许的内容

c# - Linq Union 的问题行为?

c# - 异步函数 - 使用主线程拥有的对象进行回调

spring - 如何将输入流转换为InputStreamsource或Datasource以在Spring JavaMail中附加