Thread sorunu (Comporttan dosya aktarırken)

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
seci20

Thread sorunu (Comporttan dosya aktarırken)

Mesaj gönderen seci20 »

ustalarım merhaba elimde bir adet fuction var ve dosya yazarken formda donmalar meydana gelıyor.

Foksiyon şu şekilde...

Kod: Tümünü seç

Function WriteComPort(var Buffer:TMyByteArray;BufLen,ByteToRead, TimeOut:Integer; SleepTime:Integer=100; RdTill:String=''):Integer;
var
tmpstr    :String;
ByteWr,ByteRd:Cardinal;
Res,CanRead:Boolean;
Retval:Cardinal;
DwErr:DWORD;
i,EofLen:Integer;
EofBuf,aBuf:TMyByteArray;
OvrIn       : TOverlapped;
OvrOut      : TOverlapped;
begin
  Result:=-1;
  PurgeAll();
  if BufLen > 0 then begin
    FillChar(OvrOut,SizeOf(OvrOut),0);
    OvrOut.hEvent:=CreateEvent(nil,True,False,'WrTest');
    OvrOut.Internal:=0;
    OvrOut.InternalHigh:=0;
    OvrOut.Offset:=0;
    OvrOut.OffsetHigh:=0;
    if not WriteFile(hComHandle,Buffer[0],BufLen,ByteWr,@OvrOut) then begin;
      if GetLastError = ERROR_IO_PENDING then begin
        if WaitForSingleObject(OvrOut.hEvent,TimeOut)=WAIT_OBJECT_0 then begin
          result:=0;
          Application.ProcessMessages;
          end
        else begin
          CancelIO(hComHandle);
          ResetEvent(OvrOut.hEvent);
          CloseHandle(OvrOut.hEvent);
          exit;
        end;
        CloseHandle(OvrOut.hEvent);
        end
      else begin
        Result:=0;
      end;
      end
    else begin
      result:=0;
    end;
  end;
  //Finish Write Section - Process to Read Section
  Delay2(SleepTime);
  Application.ProcessMessages;
  ByteRd:=0;
  FillChar(OvrIn,SizeOf(OvrIn),0);
  OvrIn.hEvent:=CreateEvent(nil,True,False,nil);
  OvrIn.Internal:=0;
  OvrIn.InternalHigh:=0;
  OvrIn.Offset:=0;
  OvrIn.OffsetHigh:=0;
  evMask:=EV_RXCHAR or EV_ERR or EV_BREAK;
  //evMask:=EV_RXFLAG or EV_ERR or EV_RXCHAR;
  CanRead:=False;
  Res:=WaitCommEvent(hComHandle,evMask,@OvrIn);
  if Res=False then begin //WaitCommEvent not exited only Freed
    RetVal:=GetLastError();
    if RetVal=ERROR_IO_PENDING then begin // If WaitCommEvent = IO Pending
      RetVal:=WaitForSingleObject(OvrIn.hEvent,Timeout); //Wait For it Finish/Timeout
      if RetVal=WAIT_OBJECT_0 then begin
        if evMask=EV_RXCHAR then CanRead:=True else CanRead:=False;
      end;
    end;
  end
  else begin
    if evMask=EV_RXCHAR then CanRead:=True else CanRead:=False;
  end;
  CloseHandle(OvrIn.hEvent);
  Delay2(10);

  SetLength(Buffer,0);
  if CanRead=True then begin
    SetLength(aBuf,ByteToRead);
    ZeroMemory(aBuf,ByteToRead);

    FillChar(OvrIn,SizeOf(OvrIn),0);
    OvrIn.hEvent:=CreateEvent(nil,True,False,nil);
    OvrIn.Internal:=0;
    OvrIn.InternalHigh:=0;
    OvrIn.Offset:=0;
    OvrIn.OffsetHigh:=0;

    Res:=ReadFile(hComHandle,aBuf[0],ByteToRead,ByteRd,@OvrIn);
    if Res=False then begin
      RetVal:=GetLastError;
      if RetVal=ERROR_IO_PENDING then begin
        RetVal:=WaitForSingleObject(OvrIn.hEvent,Timeout);
        if RetVal=WAIT_OBJECT_0 then begin
          GetOverlappedResult(hComHandle,OvrIn,ByteRd,False);
          SetLength(Buffer,ByteRd);
          ZeroMemory(Buffer,ByteRd);
          CopyMemory(@Buffer[0],@aBuf[0],ByteRd);
          Result:=ByteRd;
          dwErr:=0;
          FillChar(iComStat,SizeOf(iComStat),0);
          ClearCommError(hComHandle,dwErr,@iComStat);
          if iComStat.cbInQue > 0 then begin
            ByteToRead:=iComStat.cbInQue;
            SetLength(aBuf,ByteToRead);
            ZeroMemory(aBuf,ByteToRead);
            ReadFile(hComHandle,aBuf[0],ByteToRead,ByteRd,@OvrIn);
            if ByteRd > 0 then begin
              SetLength(Buffer,Result+ByteRd);
              CopyMemory(@Buffer[Result],@aBuf[0],ByteRd);
              Result:=Result+ByteRd;
            end;
          end;
          end
        else begin
          FillChar(iComStat,SizeOf(iComStat),0);
          dwErr:=0;
          ClearCommError(hComHandle,dwErr,@iComStat);
          if iComStat.cbInQue > 0 then begin
            ByteToRead:=iComStat.cbInQue;
            CloseHandle(OvrIn.hEvent);

            OvrIn.hEvent:=CreateEvent(nil,True,False,nil);
            FillChar(OvrIn,SizeOf(OvrIn),0);
            OvrIn.Internal:=0;
            OvrIn.InternalHigh:=0;
            OvrIn.Offset:=0;
            OvrIn.OffsetHigh:=0;

            SetLength(aBuf,ByteToRead);
            ZeroMemory(aBuf,ByteToRead);
            ReadFile(hComHandle,aBuf[0],ByteToRead,ByteRd,@OvrIn);
            if ByteRd > 0 then begin
              SetLength(Buffer,ByteRd);
              ZeroMemory(Buffer,ByteRd);
              CopyMemory(@Buffer[0],@aBuf[0],ByteRd);
            end;
          end;

        end;
      end;
      end
    else begin
      SetLength(Buffer,ByteRd);
      ZeroMemory(Buffer,ByteRd);
      CopyMemory(@Buffer[0],@aBuf[0],ByteRd);
      SetLength(aBuf,0);
      Result:=ByteRd;
      delay(10);
      FillChar(iComStat,SizeOf(iComStat),0);
      ClearCommError(hComHandle,dwErr,@iComStat);
      if iComStat.cbInQue > 0 then begin
        ByteToRead:=iComStat.cbInQue;
        SetLength(aBuf,ByteToRead);
        ZeroMemory(aBuf,ByteToRead);
        ReadFile(hComHandle,aBuf[0],ByteToRead,ByteRd,@OvrIn);
        if ByteRd > 0 then begin
          SetLength(Buffer,Result+ByteRd);
          CopyMemory(@Buffer[Result],@aBuf[0],ByteRd);
          Result:=Result+ByteRd;
        end;
      end;
    end;
  end;
if Length(RdTill) > 0  then begin
  SetLength(EofBuf,0);
  EofBuf:=StrtoByteArray(RdTill);
  EofLen:=Length(RdTill);
  Res:=False;
  for i:=0 to EofLen-1 do begin
    if (Buffer[(Result-EofLen)+i]=EofBuf[i]) then Res:=True else Res:=False;
  end;
  if Res=False then begin
    FillChar(iComStat,SizeOf(iComStat),0);
    ClearCommError(hComHandle,dwErr,@iComStat);
    if iComStat.cbInQue>0 then begin
      ByteToRead:=iComStat.cbInQue;

      OvrIn.hEvent:=CreateEvent(nil,True,False,nil);
      FillChar(OvrIn,SizeOf(OvrIn),0);
      OvrIn.Internal:=0;
      OvrIn.InternalHigh:=0;
      OvrIn.Offset:=0;
      OvrIn.OffsetHigh:=0;
      SetLength(aBuf,ByteToRead);
      ZeroMemory(aBuf,ByteToRead);
      ReadFile(hComHandle,aBuf[0],ByteToRead,ByteRd,@OvrIn);
      if ByteRd > 0 then begin
        SetLength(Buffer,Result+ByteRd);
        CopyMemory(@Buffer[Result],@aBuf[0],ByteRd);
        Result:=Result+ByteRd;
      end;
    end;
  end;
end;
SetLength(aBuf,0);
try
  CloseHandle(OvrIn.hEvent);
  CloseHandle(OvrOut.hEvent);
except
  application.ProcessMessages;
end;
end;
thread olarak ayarlamaya çalıştım ama malasef olmadı bu foksiyonu prosedüre cevirmem gerekli sanırsam ama başaramadım.Thread olarak ayarlamak için nasıl prosedüre cevırebılırım yada farklı bir yolu varmı kasmaması ıcın sımdıden cok tesekkur ederım...
ertank
Kıdemli Üye
Mesajlar: 1716
Kayıt: 12 Eyl 2015 12:45

Re: Thread sorunu (Comporttan dosya aktarırken)

Mesaj gönderen ertank »

Merhaba,

Aşağıdaki sorular ile ilgili cevapları paylaşabilir misiniz?
- Hangi Delphi sürümünü kullanıyorsunuz?
- Dosya nereye yazılıyor? Seri port ucuna bağlı olan cihaz nedir?
- Dosya adını string türünde parametre ile fonksiyona geçmiş olsanız ve parametredeki dosya porta yazılsa yapmak istediğiniz yine olur mu? Yoksa mutlaka TMyByteArray türünde bir bilgi mi göndermeniz gerekli?

1- TMyByteArray türünün detayı ne şekildedir?
2- PurgeAll() fonksiyon/prosedürünü paylaşabilir misiniz?
3- Delay() ve Delay2() fonksiyon/prosedürünü paylaşabilir misiniz? Bunların Sleep() ile farkları var mıdır?
4- iComStat kullandığınız bir bileşen midir? Detayını paylaşabilir misiniz?
5- StrToByteArray() fonksiyon/prosedürünü paylaşabilir misiniz?

Eğer gözden kaçan başka birşey yok ise yukarıdakileri inceledikten sonra Thread içinde kullanılıp kullanılamayacağına karar vermek daha doğru olacaktır.
seci20

Re: Thread sorunu (Comporttan dosya aktarırken)

Mesaj gönderen seci20 »

hocam sırasıyla cevap vereyim.

--Delphi xe10 kullanıyorum.
--Dosya telefona yazılıyor hocam.(Samsung markalı telefonlara).
--tmbytearray şeklinde olması lazım çünkü dosyalar o fonsiyonla yazılıyor hocam parca parca yani.Söyle bir örnek vereyim....

Kod: Tümünü seç

 SetLength(TmpBuf,$400);
    ZeroMemory(TmpBuf,Length(TmpBuf));
    TmpBuf[0]:=$66; // Binary Transfer Init

    Retval:=WriteComPort(TmpBuf,Length(TmpBuf),8,5000,10);
gibi...

--TMyByteArray = Array of Byte; şeklindedir türü TMyByteArrayın
--purgeall boş bir foksiyon yapabilirsiniz hocam forma özel bişe o.
--delay sleep komutu ıle aynı sadece formu dondumuyor o kadar.

delay kodu

Kod: Tümünü seç

procedure Delay(ms : longint);
var TheTime : LongInt;
begin
TheTime := GetTickCount + ms;
while GetTickCount < TheTime do
Application.ProcessMessages;
end;
delay 2 de aynı keza aynı hocam...

--iComStat:TCOMSTAT delphinin kendi unitinde bulunan bir bileşen hocam.

--strtobytearray foksiyonu hocam

Kod: Tümünü seç

function StrToByteArray(sStr:String):TMyByteArray;
var
ba:TMyByteArray;
begin
  SetLength(ba,length(sstr));
  MoveMemory(@ba[0],@sStr[1],length(sStr));
  result:=ba;
end;
bu arada cevap verdiğiniz için çok teşekkür ederim hocam.
ertank
Kıdemli Üye
Mesajlar: 1716
Kayıt: 12 Eyl 2015 12:45

Re: Thread sorunu (Comporttan dosya aktarırken)

Mesaj gönderen ertank »

- Hangi COM port üzerinden yazıyorsunuz? COM1, COM2, vs
- Dosya büyüklükleri ne civarda ve bu boyuttaki dosyaları mevcut kod ne kadar sürede yazıyor?

NOT: COM port bağlantı parametreleri nedir? Baud rate, stop bits, vb.
seci20

Re: Thread sorunu (Comporttan dosya aktarırken)

Mesaj gönderen seci20 »

ertank yazdı:- Hangi COM port üzerinden yazıyorsunuz? COM1, COM2, vs
- Dosya büyüklükleri ne civarda ve bu boyuttaki dosyaları mevcut kod ne kadar sürede yazıyor?

NOT: COM port bağlantı parametreleri nedir? Baud rate, stop bits, vb.
hocam comport değişkenlik gösterebiliyor yani sabit değil.
-- dosya boyutları max 3 gb hocam.
--Baud rate:=115200
--stop bits:=1
--databits:=8
hocam
Cevapla