I'm connecting a legacy application (written in COBOL) with our .NET new ones using pipes.
The idea is simple: The legacy program (my ERP Menu) writes some parameters upon the stream, the .NET app reads it thru Console.In
stream and starts a new thread opening the screen requested. Here's a snippet from the .NET side of how the idea works:
<STAThread(), LoaderOptimization(LoaderOptimization.MultiDomain)>
Shared Sub Main()
If Environment.GetCommandLineArgs(1) = "PIPE"
While True
Dim pipeParam as String
Try
pipeParam = Console.In.ReadLine()
Catch e as Exception
Exit Sub
End Try
' Deal with parameters here
If pipeParam = "END"
Dim newThread as New Threading.Thread(Sub()
' Create a new AppDomain and Loads the menu option, generally a Winforms form.
End Sub)
newThread.Start()
End If
End While
End If
End Sub
Everything was working fine and easy... until today.
I deployed this solution in my client environment (Windows Server 2003), and it happened that none of the threads requested were being executed, except when the called process (COBOL) was being terminated (that is, the Console.In
was being forcedly closed). From then on, all the requested winforms will start showing up and behaving as expected.
Digging this strange behaviour with logs, I found out that the threads were being normally executed until a point that a IDictionary.ContainsKey()
statement was performed (or some other method that requires native code execution). At this point, the thread was freezing / sleeping.
If I limit the thread creation to, let say, three, it happens that every created thread hangs until the third one, that is, when Console.In.ReadLine
is not executed anymore.
What should I try? Any advices?
Some more info: The closest direction I've found so far was the Hans Passant's answer in this question: Interface freezes in multi-threaded c# application (the .NET SystemEvents happens to appear in my debbuger thread list, but I couldn't solve my problem with the proposed solution).
UPDATED NEWS
I could solve this issue by waiting the sub-thread to finish load the Form
. This "Is Ready" signal is passed through AppDomain.SetData()
and AppDomain.GetData()
. Somehow, after the form creation the sub-thread doesn't freezes anymore when the main one goes on Console.ReadLine
. Though the problem is solved, I'm intrigued with this. I'm trying to reproduce this in a "simple as possible" test case.
Some More Details
- The entry-point .exe is compiled to 32-bit. All other libraries are 'AnyCpu'. The issue happens running on both 32-bits (my client) and 64-bits (my development) machines (both windows Server 2003).
- Updated
Sub Main()
attributes in the above snippet. - Tried to put the
Console.ReadLine
in a worker thread. Didn't solved (see image below). - The COBOL application won't freeze, because it is executed in a separate OS Process. The pipe happens to be my IPC approach. The COBOL application in this case only writes parameters and don't wait for response.
- The stack trace is in the image below (the thread
PRX001235
is deserializing an xml config file before connecting to the database and before effectively loading the form - in this case, seems to be still in managed code - sometimes thePRX001235
thread will freeze in native code when trying to connect to the database):