How to debug remote .NET calls?

I have an application with the following basic architecture:

A Windows service (Service) that registers a .NET type (RemoteObject) for remote access (.NET Remoting). RemoteObject creates threads without ThreadPool that use ThreadPool to process I / O. ThreadPool size should be limited by the limit for a specific reason. The GUI application uses .NET Remoting to access RemoteObject.

I noticed that if the size of ThreadPool is too low, the GUI application will hang when calling RemoteObject.

My question is, how can I understand why this is hanging, and why will the RemoteObject thread be affected by ThreadPool?

It drives me crazy; thank you for your help!

+6
multithreading remoting
source share
4 answers

It turns out that the .NET remoting infrastructure uses .NET ThreadPool (or shares the main resource), so remote calls may hang if all ThreadPool threads are used by your application.

+4
source share

I am not sure if this will help (I cannot say if this is your problem or not), but if you want to debug your service as its launch, you can tickle it in your code:

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

and you will get a dialog box asking you to select a debugger. This is an easy way to connect to a running instance of a service. If nothing else, this will allow you to break into your service when the user interface hangs (by clicking the pause button on the debug toolbar) and check your threads and stop code.

+4
source share

It may not be very useful, but I’ll give it up anyway.

When debugging services and clients that speak via remote access, usually I always run two instances of the debugger: one for the client and one for the service. To be clear, I am launching two copies of the visual studio. For this service, you can use the attach command, or you can directly change the main and initial calls (bypassing the entire service code).

This is how I usually turn on debugging, changing the main one, you will have to call DebugService for the service, it really is just an entry point that calls the beginning. As soon as I have this, I will simply enable utility debugging by defining SERVICE_DEBUG or changing #if , adding ' !' . Now you basically converted your service to a console application.

 #if SERVICE_DEBUG ServiceHost s = new ServiceHost(); s.DebugService(); Thread.Sleep( 300000000 ); #else ServiceBase.Run( ServicesToRun ); #endif 

After installation and launch, you can go through the client, when remote calls get into the service, you can go through the service code, allowing you to simultaneously debug both.

Out of curiosity, are you invoking a remote object directly from the GUI thread? If so, the GUI thread will block until the remote call is completed. This will block the entire graphical interface and make it immune. This is not a solution to the problem, but if it is, and the service flow is not returned, this will lead to a hang of the graphical interface.

+2
source share

A few years ago, I developed and implemented a critical business system using .NET Remoting. We had a client implemented as a Windows Forms GUI, a server implemented as a Windows service, and a SQL Server database.

I developed it for troubleshooting / debugging / development, so one of my first design criteria was that I could trivially remove the entire .NET Remoting implementation and run the entire system on my desktop. That way, I could turn off remote access by changing one boolean configuration setting to "false" = off. Then I could troubleshoot, debug, fully develop without the overhead or the intervention of .NET Remoting.

It seems that it would be useful for your situation. In fact, I cannot imagine a situation where this is not a desirable feature, especially since it is easy to implement.

So, to implement it, the configuration parameter was used by each of the client and server code to decide which implementation class to create to communicate with the other side. All communication was carried out through the C # user interface, which had two specific implementation classes on each side: one class implemented communication using .NET Remoting, the other class implemented communication as a direct end-to-end study (direct calls).

Only one pair of classes (one on each side) knew something about .NET Remoting, so the isolation was complete. In most cases, all developers worked with deletion turned off, which was faster and easier. When they needed, in rare cases, they turned it on (mostly just me, or when someone connected to testing / production for troubleshooting).

By the way, I made the remote control interface simple: public Response execute (Request)

In addition, I also used the debugger startup tip mentioned above, and I agree that you need to be aware of the effect on GUI threads.

+1
source share

All Articles