如何在.NET 6中为自定义无参数类创建ObjectPool?

ryoqjall  于 2023-03-04  发布在  .NET
关注(0)|答案(1)|浏览(96)

这是我问的a previous SO question的延续。
我正在尝试创建一个ObjectPool的FTP客户端。由于"连接"步骤,FTP客户端使用起来很昂贵。所以我想-〉让它们池化,这样在初始连接步骤之后,我们就可以 * 重用 * 这些连接的FTP客户端!
我现在尝试使用Microsoft.Extensions.ObjectPool nuget/library来启用类库创建ObjectPool。我还希望确保我 * 最多 * 只能有100个FTP客户端,因为目标FTP服务器 * 同时 * 最多有100个客户端连接。
对于下面的MyFtpClient类,我不确定如何执行此操作:

public class MyFtpClient : IMyFtpClient
{
    private readonly RealFtpClient _realFtpClient;

    public MyFtpClient(string host, string username, string password)
    {
        // initialize FTP client
        _realFtpClient = new RealFtpClient(host, username, password);
    }

    public async Task UploadFileAsync(Stream someFile, CancellationToken ct)
    {
        // upload file using FTP client
        await _realFtpClient.UploadFile(someFile, ct);
    }
}

我想我可以试试这个:

var objectPool = new DefaultObjectPool<MyFtpClient>(new DefaultPooledObjectPolicy<MyFtpClient>(), 100);

但这不起作用因为MyFtpClient不是无参数的。
有人能帮我演示一下我该怎么做吗?
对于更多的上下文,我从队列中抓取消息,然后将消息上下文推送到ftp服务器。我一次拉下100条消息。(如果队列中的消息少于100条,那么它将只返回全部消息,如20 msgs或55 msgs等)。
因此对于GetMessagesFromQueue中的每一条消息:

  • 获得MyFtpClient
  • 获取Task以将消息上载到ftp服务器。
  • await Task.WhenAll(tasks);〈--现在等待所有这些上传,最大值为100。

有人能帮忙吗?

58wvjzkj

58wvjzkj1#

您可以创建自己的自定义PooledObjectPolicy,该PooledObjectPolicy实现IPooledObjectPolicy<MyFtpClient>并在其构造函数中获取连接细节,调用Create()方法。

public class MyFtpClientPooledObjectPolicy : IPooledObjectPolicy<MyFtpClient>
{
    private string _host;
    private string _username;
    private string _password;
    
    public MyFtpClientPooledObjectPolicy(
        string host, string username, string password)
    {
        _host = host;
        _username = username;
        _password = password;
    }
    
    public MyFtpClient Create()
    {
        return new MyFtpClient(_host, _username, _password);
    }

    public bool Return(MyFtpClient obj)
    {
        return true;
    }
}

这允许您按如下方式创建池:

var host = string.Empty;
var username = string.Empty;
var password = string.Empty;
var objectPool = new DefaultObjectPool<MyFtpClient>(
    new MyFtpClientPooledObjectPolicy(host, username, password), 100);

相关问题