Met strange error when using pinvoke to call ReadFile in background thread - pinvoke

What I am doing is writing a WPF application to work with our device. The application writes some commands to the device and reads command's response from it. I got pinvoke declarations from pinvoke.net website for CreateFile, WriteFile, ReadFile, etc.
I made a function doing following things, CreateFile(with flag FILE_FLAG_OVERLAPPED
) to open device, WriteFile to send command, ReadFile to read response, WaitForSingleObject and GetOverlappedResult to capture timeout exception if device doesn't respond, and CloseHandle to close device.
This function always worked fine if I called it in UI thread. But I wanted to call it in background thread to keep UI active. So I created a thread in Window_Loaded method(Work is my function's name).
t = new Thread(Work);
t.Start();
Then ReadFile, WaitForSingleObject and GetOverlappedResult group may met error, these three functions returned success and GetOverlappedResult could capture correct read length returned from device. But no actual data read from device filled in the byte array buffer passed to ReadFile function. The failure rate was about 50%.
If I waited thread t to finish, then it always worked fine again.
t = new Thread(Work);
t.Start();
t.join();
Of cause UI would also hang in this situation.
I searched this problem but no exact same question was found. I tried to set background thread's apartment state to STA or MTA explicitly, but it didn't work.
t = new Thread(Work);
t.SetApartmentState(ApartmentState.STA);
t.Start();
It really confuses me. Please help me if you have any idea. Thank you for your reading.

I couldn't find the root cause. But I bypassed it by rewriting read process in C++ function and calling my C++ function with pInvoke.

Related

MarshalByRefObject causing C++ program to hang

I have a client program that uses a MarshalByRefObject to get a variable from a remote server. Sometimes the program hoses up on the remote server and when I try to get that variable my client program simply hangs. Is there a way to time out the call on this variable?
MyClass^ refObject = (MyClass^)System::Activator::GetObject(MyClass::typeid, url);
THEVARIABLE objectVariable = refObject->theVariable;
The only way I see is to implement an IMessageFilter (COM). In some cases it is possible to detect that there is an out of process call from the current STA to another. But AFAIK this is only done when an input message (keyboard/mouse) arrives.
With a message filter you can show something like "waiting for external com call...". Also in this case you may abort the external call.
See CoRegisterMessageFilter, and IMessageFilter

IDXGIFactory->CreateSwapChain sets system error 0X594

I am working on a system where I want to intercept Direct3D calls to create tiled displays. I am using an APITrace like interceptor to create a message stream and recreating the calls in a second program, much like the old Chromium project. The application side works fine but the program that processes the message stream does not. What I find is that when I call CreateSwapChain() the function returns S_OK but GetLastError() returns 'error = 0x00000594 : Cannot set nonlocal hook without a module handle.' I check the error state with GetLastError() just prior to calling CreateSwapChain() and there is no error. This error makes no sense to me. Can anyone shed any light on this?
I found the problem. The parameters for the CreateSwapChain function the pDesc structure includes an output window handle. Since the message stream is packed with the arguments for the message processing side the window handle has to be replaced with correct handle before the function is called be the processor side.

Stackoverflowexception - Unable to find out the cause

Second question on here...
Basically I am having a problem with a Stackoverflow exception that is thrown in my program, and I literally have no idea on how to locate the cause..
I have a program which has a plugin system, and it's a program that utilizes TCP in order to send and receive data; Server-> Client. I am making a remote console plugin, and the problem occurs when I do the command 'tree'; the filesystem entries listing command. For the first few seconds everything goes alright; the commands are being outputted (sent from Client to server). The receiving packets event isn't thread safe, so in the API I've provided an invocation function (to invoke methods on the UI thread). So therefore on output, it will do the following:
Public Sub ClientReadPacket(Sender As IClient, Pipename As String, Values As Object())
Select Case DirectCast(Values(1), ConsoleCommands)
Case ConsoleCommands.Output
ServerGUI.Send(Sub() ConsoleOutput.AppendText(Values(2) & Environment.NewLine))
End Select
End Sub
As you can see, the ServerGUI is an interface that I have provided for plugin development. And in the actual program - in the class that implements the GUI interface, I get a stackoverflow exception right here:
Private Sub ISend(del As System.Threading.SendOrPostCallback) Implements IGUI.Send
UIThread.Send(del, Nothing)
End Sub ' The break point is here; I assume that means that the exception ocurs in the line above.
The UIThread object is a synchronizationcontext of the main thread.
http://i.gyazo.com/870d9667f2272969b650cea836adca50.png
Update: So far I've narrowed it down to the following; it must be causing stackoverflow exception when calling SynchronizationContext.Send() too often, and the same happens when I rather use Invoke() in the plugin, it also gives a Stackoverflow exception.
I tried using asyncoperation, and this does not crash, but due to the fact that it's solely asynchronous is a problem, because my program becomes unresponsive when using Post(), because it continuously Posts (due to the fact that it will manage the next packet before the asyncoperation has posted.

.Net Asynchronous Delegate Abortion

Background: My application is used to execute tests using Selenium RC servers, and occasionally I'm running into a problem when my call to a Selenium command doesn't return the response from the RC server - it then ends up blocking the thread that is executing the test.
Sample Code:
Private Delegate Function DoCommand_Delegate(ByVal command As String, ByVal args() As String) As String
...
asyncCommand = New DoCommand_Delegate(AddressOf server.DoCommand)
asyncResult = asyncCommand.BeginInvoke(command, args, Nothing, Nothing)
Try
... (I have it use the AsyncWaitHandle to wait for periods of 10 seconds up to two minutes. At the end of each period it runs some checks for common problems that block Selenium from returning a response (modal dialogs) - I don't think that part is relevant to this question, it's just necessary.)
Finally
result = asyncCommand.EndInvoke(asyncResult)
...
At the time EndInvoke is called, the worker delegate has either already finished or needs to be aborted. Most of the time it already has a response so it works just fine, but on rare occasion Selenium RC's DoCommand doesn't return, so the thread sits there locked.
Finally, my question: is there a resource-friendly way to abort the executing delegate, or do I need to convert it to use a manually controlled thread that can be aborted and disposed?
Note: This is not a question regarding Selenium, just proper multithreading.
Note 2: I've considered doing the following in the Finally before calling EndInvoke:
If Not asyncResult.IsCompleted Then asyncResult.AsyncWaitHandle.Close()
... But I don't know if that would actually work correctly, or what damage that could cause.
There is no way to do the following at the same time:
Abort/kill a thread non-cooperatively
Without destroying all state associated with it (AppDomain/process)
Implies: Either terminate cooperatively (not possible here) or kill the process (AppDomain not enough because native state is involved) or don't kill the thread.
You could just not kill the thread and leave it there hanging. The rest of your program (the remaining tests) can continue to execute.
I'd not be happy to see this in production but for a test suite this could be ok (assuming the hang cannot be fixed).
Why can't a thread be aborted? This has been covered a number of times on Stack Overflow already.

DuplicateHandle, why duplicate instead of just acquire?

Why would a process want to call DuplicateHandle from the Win32API, and get it from another process instead of just acquiring the handle on some object itself?
Is there some advantage to calling DuplicateHandle or something?
You may find the answer in Chapter 6.8 of 'Programming Applications for Microsoft Windows'.
Gaining a Sense of One's Own Identity
Sometimes you might need to acquire a real handle to a thread instead of a pseudo-handle. By "real," I mean a handle that unambiguously identifies a unique thread. Examine the following code:
DWORD WINAPI ParentThread(PVOID pvParam) {
HANDLE hThreadParent = GetCurrentThread();
CreateThread(NULL, 0, ChildThread, (PVOID) hThreadParent, 0, NULL);
// Function continues...
}
DWORD WINAPI ChildThread(PVOID pvParam) {
HANDLE hThreadParent = (HANDLE) pvParam;
FILETIME ftCreationTime, ftExitTime, ftKernelTime, ftUserTime;
GetThreadTimes(hThreadParent,
&ftCreationTime, &ftExitTime, &ftKernelTime, &ftUserTime);
// Function continues...
}
Can you see the problem with this code fragment? The idea is to have the parent thread pass to the child thread a thread handle that identifies the parent thread. However, the parent thread passes a pseudo-handle, not a real handle. When the child thread begins executing, it passes the pseudo-handle to the GetThreadTimes function, which causes the child thread to get its own CPU times, not the parent thread's CPU times. This happens because a thread pseudo-handle is a handle to the current thread— that is, a handle to whichever thread is making the function call.
To fix this code, we must turn the pseudo-handle into a real handle. The DuplicateHandle function (discussed in Chapter 3) can do this transformation
One possible use of DuplicateHandle is to duplicate a handle between a 32-bit process and a 64-bit process.
Note: cannot be used on I/O Completion ports or Sockets.
Another use of DuplicateHandle is to open a file in multiple processes when the file uses FileOptions.DeleteOnClose. (such a file cannot be opened by multiple processes if the file path is used to open the file)
See my answer at https://stackoverflow.com/a/36606283/2221472
See here on the MSDN what it has to say about the usage of 'DuplicateHandle'. The best way I can think of it is this way, an analogy if you like - suppose you open a file using the CreateHandle routine for writing only, then you call DuplicateHandle to pass the handle onto another thread in which the thread will read from the file, only the handle is duplicated hence the thread does not have to call CreateHandle again...