如何调试.NET远程调用?

时间:2008-11-06 18:12:43

标签: .net multithreading remoting

我有一个具有以下基本架构的应用程序:

注册.NET类型(RemoteObject)以进行远程访问(.NET Remoting)的Windows服务(服务)。 RemoteObject创建使用ThreadPool进行IO处理的非ThreadPool线程。由于特定原因,必须将ThreadPool的大小限制为限制。 GUI应用程序使用.NET Remoting来访问RemoteObject。

我注意到如果ThreadPool的大小太小,GUI应用程序将在调用RemoteObject时挂起。

我的问题是,如何弄清楚为什么会挂起,以及为什么RemotePit会受ThreadPool影响?

这让我发疯;谢谢你的帮助!

4 个答案:

答案 0 :(得分:4)

我不确定这是否会有所帮助(我无法判断这是否是您的问题),但如果您想将服务调试为运行,则可以在代码中使用它:

#if DEBUG
            if (!System.Diagnostics.Debugger.IsAttached)
                Debugger.Launch();
#endif

然后你会得到一个对话框,要求你选择一个调试器。它是一种附加到正在运行的服务实例的简单方法。如果没有别的,这将让你在UI挂起时进入你的服务(通过按调试工具栏上的暂停按钮)并检查你的线程和callstack。

答案 1 :(得分:4)

事实证明,.NET远程处理基础结构使用.NET ThreadPool(或共享底层资源),因此如果应用程序正在使用所有ThreadPool线程,则远程调用可能会挂起。

答案 2 :(得分:2)

这可能不是特别有用,但无论如何我都会把它扔掉。

在调试通过远程处理的服务和客户端时,我通常会运行两个调试器实例:一个用于客户端,另一个用于服务。为了清楚起见,我正在运行两个视觉工作室副本。对于服务,您可以使用attach命令,也可以直接更改main和call start(绕过所有服务代码)。

以下是我通常通过改变main来启用调试的方法,你必须和DebugService调用该服务,它实际上只是一个调用start的入口点。完成此操作后,我只需通过定义SERVICE_DEBUG或通过添加“#if更改!'来启用服务调试。现在,您基本上已将服务转换为控制台应用程序。

#if SERVICE_DEBUG
            ServiceHost s = new ServiceHost();
            s.DebugService();
            Thread.Sleep( 300000000 );

#else
            ServiceBase.Run( ServicesToRun );
#endif

一旦您同时设置并运行,您就可以单步执行客户端,当远程调用点击服务时,您可以单步执行服务代码,允许您同时调试两者。

出于好奇你是直接从GUI线程调用远程对象吗?如果是这样,GUI线程将阻塞,直到远程调用完成。这将锁定整个GUI并使其无响应。这不是问题的解决方案,但如果是这种情况并且您的服务线程没有返回,那么它也会导致GUI挂起。

答案 3 :(得分:1)

几年前,我设计并实现了一个使用.NET Remoting的关键业务系统。我们将客户端实现为Windows窗体GUI,实现为Windows服务的服务器和SQL Server数据库。

我是为故障排除/调试/开发而设计的,所以我的第一个设计标准之一是我可以轻松删除整个.NET Remoting实现并在我的桌面上运行整个系统。因此,我可以通过将单个布尔配置设置更改为“false”= off来停用远程处理。然后,我可以在没有.NET Remoting的开销或干扰的情况下进行故障排除,调试,完全开发。

这似乎对你的情况也很有价值。事实上,我无法想象这种情况不是一个理想的特征,特别是因为它很容易实现。

因此,为了实现它,每个客户端和服务器代码使用配置设置来决定实例化哪个实现类以与另一方进行通信。所有通信都是通过自定义C#接口进行的,每个接口都有两个具体的实现类:一个类使用.NET Remoting实现通信,另一个类将通信实现为直接进程间直通(直接调用)。

只有一对类(每侧一个)了解.NET Remoting,所以隔离是完全的。大多数时候,所有开发人员都关闭了远程处理,这更快,更简单。当他们需要时,在极少数情况下,他们打开它(主要是我,或者当有人连接到测试/生产进行故障排除时)。

顺便说一句,我让远程接口变得简单:     public Response execute(Request)

除此之外,我还使用了上面提到的调试器启动技巧,我同意你需要注意对GUI线程的影响。