C# zaman aşımlı WriteFile ve ReadFile

Başlatan hasankara, 21 Eylül 2015, 18:05:29

hasankara

USB hid aygitla haberleşmek üzere aşağıda yazmış olduğum fonksiyon istediğim gibi çalışmakta. Yalnız farkettiğim üzere, timeout özelliği kazandırmak için overlapped yapısında ReadFile fonksiyonunu çağırınca overlapped olmadığı haline göre 2 kat daha yavaş çalışıyor ve bazı okuma işlemlerinde 10larca kat yavaşlayabiliyor.

        public unsafe bool ReadFileManagedBuffer(SafeFileHandle hFile, byte[] INBuffer, uint nNumberOfBytesToRead, ref uint lpNumberOfBytesRead, IntPtr lpOverlapped)
        {
            IntPtr pINBuffer = IntPtr.Zero;


            try
            {
                pINBuffer = Marshal.AllocHGlobal((int)nNumberOfBytesToRead);    //Allocate some unmanged RAM for the receive data buffer.

                var security = new SECURITY_ATTRIBUTES();
                var overlapped = new NativeOverlapped();
                var overlapTimeout = timeout <= 0 ? WAIT_INFINITE : timeout;

                security.lpSecurityDescriptor = IntPtr.Zero;
                security.bInheritHandle = true;
                security.nLength = Marshal.SizeOf(security);

                overlapped.OffsetLow = 0;
                overlapped.OffsetHigh = 0;
                overlapped.EventHandle = CreateEvent(ref security, Convert.ToInt32(false), Convert.ToInt32(true), string.Empty);

                swfirst = stopwatch.ElapsedTicks;
                ReadFile(hFile, pINBuffer, nNumberOfBytesToRead, ref lpNumberOfBytesRead, ref overlapped);

                var result = WaitForSingleObject(overlapped.EventHandle, overlapTimeout);

                swlast = stopwatch.ElapsedTicks;
                swdif = swlast - swfirst;
                swnew = true;

                switch (result)
                {
                    case WAIT_OBJECT_0:
                        {
                            Marshal.Copy(pINBuffer, INBuffer, 0, (int)lpNumberOfBytesRead);    //Copy over the data from unmanged memory into the managed byte[] INBuffer
                            Marshal.FreeHGlobal(pINBuffer);
                            return true;

                        }
                    case WAIT_TIMEOUT:

                    case WAIT_FAILED:

                    default:
                        Refresh();
                        Marshal.FreeHGlobal(pINBuffer);
                        return false;
                }
            }
            catch
            {
                if (pINBuffer != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pINBuffer);
                }
                return false;
            }
        }


Bu yavaşlama durumundan dolayı overlapped yapısını kullanmadan, ReadFile fonksiyonuna timeout özelliği kazandırmak için başka bir metod geliştirdim. ReadFile fonksiyonu çalışmasını sürdürürken backgroundworker ile geçen zamanı takip ediyorum. eşik değerin üzerine çıktığı zaman ise ReadFile da kullanılan dosyayı dispose ve close ediyorum. Yalnız ReadFile fonksiyonu çalışmasını bir türlü sonlandıramadım.

        public unsafe bool ReadFileManagedBuffer(SafeFileHandle hFile, byte[] INBuffer, uint nNumberOfBytesToRead, ref uint lpNumberOfBytesRead, IntPtr lpOverlapped)
        {
            IntPtr pINBuffer = IntPtr.Zero;

            try
            {
                pINBuffer = Marshal.AllocHGlobal((int)nNumberOfBytesToRead);    //Allocate some unmanged RAM for the receive data buffer.

                toutSave = swTout.ElapsedMilliseconds;
                touten = true;

                swfirst = stopwatch.ElapsedTicks;
                if (ReadFile(hFile, pINBuffer, nNumberOfBytesToRead, ref lpNumberOfBytesRead, lpOverlapped))
                {
                    touten = false;

                    swlast = stopwatch.ElapsedTicks;
                    swdif = swlast - swfirst;
                    swnew = true;

                    Marshal.Copy(pINBuffer, INBuffer, 0, (int)lpNumberOfBytesRead);    //Copy over the data from unmanged memory into the managed byte[] INBuffer
                    Marshal.FreeHGlobal(pINBuffer);

                    return true;
                }
                else
                {
                    Marshal.FreeHGlobal(pINBuffer);
                    return false;
                }


            }
            catch
            {
                if (pINBuffer != IntPtr.Zero)
                {
                    Marshal.FreeHGlobal(pINBuffer);
                }
                return false;
            }
        }


        private void ReadWriteTimeOut_DoWork(object sender, DoWorkEventArgs e)
        {
            while (true)
            {
                long toutlim = 50;
                long reg =0 ;
                //reg = toutSave;
                while (swTout.ElapsedMilliseconds - toutSave < toutlim || touten == false) ;

                //WriteHandleToUSBDevices[DPathInd].Close();
                //ReadHandleToUSBDevices[DPathInd].Close();

                WriteHandleToUSBDevices[DPathInd].Dispose();
                ReadHandleToUSBDevices[DPathInd].Dispose();

                AttachedButBrokens[DPathInd] = true;
                AttachedStates[DPathInd] = false;

                //Refresh();

                touten = false;
            }
        }


Asıl sorum şu; Asenkron çalışan backgroundworker dan ReadFile fonksiyonunun çalışmasını nasıl durdurabilirim?


Gökhan BEKEN

Ben c# ile dosya okuma yazma işlemlerinde testler yaptım, yavaş okuyor ve belli bir büyüklükten fazlasını okurken hata veriyor.
C dili ile bir dll yazıp onu c#'a çağırarak kullanmanı tavsiye ederim.
Özel mesaj okumuyorum, lütfen göndermeyin.

hasankara

evet ortam c#, ancak ReadFile fonksiyonunu kernel32.dll den import ediyorum. Yani şimdi kernel32 hiç kullanma mı demiş oluyorsun?