c# - 在 TPL 任务中包装 .NET Remoting 异步方法

标签 c# task-parallel-library remoting

我们有一个遗留的基于 .NET Remoting 的应用程序。我们的客户端客户端库目前仅支持同步操作。我想添加基于 TPL 的异步操作 async Task<>方法。

作为概念证明,我已经根据 these instructions 的修改版本设置了一个基本的远程处理服务器/客户端解决方案。 .

我还找到了this article描述了如何将基于 APM 的异步操作转换为基于 TPL 的异步任务(使用 Task.Factory.FromAsync )

我不确定的是我是否必须在 .BeginInvoke() 中指定回调函数并指定 .EndInvoke() .如果两者都需要,回调函数和.EndInvoke()之间到底有什么区别? .如果只需要一个,我应该使用哪个来返回值并确保我 have no memory leaks .

这是我当前的代码,我没有将回调传递给 .BeginInvoke() :

public class Client : MarshalByRefObject
{
    private IServiceClass service;

    public delegate double TimeConsumingCallDelegate();

    public void Configure()
    {
        RemotingConfiguration.Configure("client.exe.config", false);

        var wellKnownClientTypeEntry = RemotingConfiguration.GetRegisteredWellKnownClientTypes()
            .Single(wct => wct.ObjectType.Equals(typeof(IServiceClass)));

        this.service = Activator.GetObject(typeof(IServiceClass), wellKnownClientTypeEntry.ObjectUrl) as IServiceClass;
    }

    public async Task<double> RemoteTimeConsumingRemoteCall()
    {
        var timeConsumingCallDelegate = new TimeConsumingCallDelegate(service.TimeConsumingRemoteCall);

        return await Task.Factory.FromAsync
            (
                timeConsumingCallDelegate.BeginInvoke(null, null),
                timeConsumingCallDelegate.EndInvoke
           );
    }

    public async Task RunAsync()
    {
        var result = await RemoteTimeConsumingRemoteCall();
        Console.WriteLine($"Result of TPL remote call: {result} {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}");
    }
}

public class Program
{
    public static async Task Main(string[] Args)
    {
        Client clientApp = new Client();
        clientApp.Configure();

        await clientApp.RunAsync();

        Console.WriteLine("Press any key to continue...");
        Console.ReadKey(false);
    }
}

最佳答案

回调函数与 .EndInvoke() 之间的区别在于,回调函数将在线程池中的任意线程上执行。如果您必须确保从与调用 BeginInvoke 的线程相同的线程上读取结果,则不应使用回调,而应轮询 IAsyncResult 对象并在以下时间调用 .EndInvoke()操作完成。

如果您在 .Beginnvoke() 之后立即调用 .EndInvoke(),您将阻塞线程直到操作完成。这会起作用,但扩展性很差。

所以,你所做的似乎没问题!

关于c# - 在 TPL 任务中包装 .NET Remoting 异步方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53154723/

相关文章:

c# - C# 中的 SSL 握手?

c# - 如何访问调用异步方法时可用的变量?

.net - 检查 .NET 远程服务器是否存在 - 我的方法是否正确?

c# - 使用 HTTP Location Header、HttpWebRequest/Response 和 Response.Cookies.Add() 将用户重定向到使用表单例份验证的身份验证页面

c# - 与基准测试相比,StackExchange redis 客户端非常慢

c# - 动态创建的按钮未触发按钮单击事件

c# - WCF 初始化慢与 .NET 远程处理

c# - 使用 HttpClient.GetAsync 调用 Web API 似乎挂起

c# - 有什么方法可以使用 ContinueWith 任务来启动任务吗?

C#:让我的程序调用同一台机器上正在运行的进程的方法