Hi,
We are using a C++ dll from our C# code.
The C++ code reads data from a serial communication port, and fills up a buffer with the data read.
We are sometimes experiencing a big delay (around 5 seconds) when the C++ function returns.
The C# code looks something like this:
class Program    
{
 
[DllImport("SerialCommunication.dll", EntryPoint = "SerialCommRead", SetLastError = true)]
protected static extern unsafe SERIAL_COM_STATUS SerialCommRead(uint handle, 
   [MarshalAs(UnmanagedType.LPArray)] byte[] buffer,
    uint length, [MarshalAs(UnmanagedType.LPArray)] uint[] bytesRead);
 
protected void Read()
{
  StreamWriter logWriter = new new StreamWriter("test.log", true);
  SERIAL_COM_STATUS status = SerialCommRead(m_PortHandle, m_ReadBuffer,(uint)m_ReadBuffer.Length, bytesRead);
  DateTime t = DateTime.Now;
  logWriter.Write(t.Day.ToString() + "/" + t.Month.ToString() + "/" + t.Year.ToString() + " " +
     t.Hour.ToString() + ":" + t.Minute.ToString() + ":" + t.Second.ToString() + "." + 
     t.Millisecond.ToString() + " ");
  logWriter.WriteLine("After SerialCommRead(), status: " + status.ToString() + " bytesRead: " + 
     bytesRead[0].ToString());
  logWriter.Flush();
}
}
 
 
The C++ code:
 
__declspec(dllexport) SERIAL_COM_STATUS SerialCommRead(HANDLE handle, unsigned char *buffer, 
unsigned int length, unsigned int *bytesRead)
{           
            COMSTAT ComStat;
            DWORD errorFlags, err;
            *bytesRead = 0;
            OVERLAPPED overlappedRead;
            memset(&overlappedRead, 0, sizeof(OVERLAPPED));
            overlappedRead.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
            if (!overlappedRead.hEvent) {
                        err = GetLastError();
                        return(SER_COM_CREATE_EVENT_ERROR);
            }
            if (!ClearCommError(handle, &errorFlags, &ComStat)) {
                        err = GetLastError();
                        CloseHandle(overlappedRead.hEvent);
                        return(SER_COM_READ_ERROR);
            }
            if (!ComStat.cbInQue) {
                        CloseHandle(overlappedRead.hEvent);
                        return(SER_COM_OK); // There is nothing in queue to read
            }
            DWORD numOfBytesRead = 0;
            if (!ReadFile(handle, (LPVOID)buffer, (DWORD)length, &numOfBytesRead, &overlappedRead)) {
                        err = GetLastError();
                        if (ERROR_IO_PENDING == err) {
                                    DWORD res = WaitForSingleObject(overlappedRead.hEvent, SER_COM_OVERLAP_READ_TIMEOUT);
                                    switch (res) {
                                                case WAIT_OBJECT_0:
                                                            if (!GetOverlappedResult(handle, &overlappedRead, &numOfBytesRead, TRUE)) {
                                                                        err = GetLastError();
                                                                        CloseHandle(overlappedRead.hEvent);
                                                                        return(SER_COM_GET_OVERLAP_ERROR);
                                                            }
                                                            break;
                                                case WAIT_TIMEOUT:
                                                            *bytesRead = (unsigned int)numOfBytesRead;
                                                            CloseHandle(overlappedRead.hEvent);
                                                            return(SER_COM_TIMEOUT_ERROR);
                                                case WAIT_FAILED:
                                                            err = GetLastError();
                                                            *bytesRead = (unsigned int)numOfBytesRead;
                                                            CloseHandle(overlappedRead.hEvent);
                                                            return(SER_COM_WAIT_ERROR);
                                                default:
                                                            *bytesRead = (unsigned int)numOfBytesRead;
                                                            CloseHandle(overlappedRead.hEvent);
                                                            return(SER_COM_ERROR);
                                    }
                        } else {
                                    CloseHandle(overlappedRead.hEvent);
                                    return(SER_COM_READ_ERROR);
                        }
            }
            CloseHandle(overlappedRead.hEvent);
            *bytesRead = (unsigned int)numOfBytesRead;
            PrintToFile("SerialCommRead(): going to return");
            return(SER_COM_OK);
}
 
void PrintToFile(char *str)
{
            struct _timeb timebuffer;
            _ftime( &timebuffer );
            char timeline[26];
            ctime_s( timeline, 26, & ( timebuffer.time ) );
            static FILE *fHandle = NULL;
            if (NULL == fHandle)
            {
                        // First time, open th file
                        fHandle = fopen(“test2.log”, "wt");
            }
            if (fHandle) {
                        fprintf(fHandle, "%.19s.%hu ", timeline, timebuffer.millitm);
                        fprintf(fHandle, "%s\n", str);
                        fflush(fHandle);
            }
}
 
In file “test2.log” the printout of “SerialCommRead(): going to return” appears with a timestamp that is sometimes 5 seconds earlier than the printout to “test.log” from the C# code. 
Looks like it takes the C++ function 5 seconds to return…
 
Any ideas?
 
Thanks,
 
            Galit.