question about threading

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
Kullanıcı avatarı
mia
Üye
Mesajlar: 239
Kayıt: 17 Nis 2015 02:18

question about threading

Mesaj gönderen mia »

selam alykom , i have question about threading if i run two threads together it can be problem to other thread ?

i mean if i have thread called download and other called runalways

if runalways thread executed can effect on download thread if its executed in the same time ?
بِسْمِ اللهِ الرَّحْمنِ الرَّحِيمِ
in god i trust with every movement i do
graduated student and looking for knowledge
Kullanıcı avatarı
freeman35
Admin
Mesajlar: 2381
Kayıt: 12 Haz 2003 04:05
Konum: merkez camii yanı

Re: question about threading

Mesaj gönderen freeman35 »

You can think like a each thread is a different application, for example, first thread is downloading file, second thread is try to run or extract this file. you can get error, 'cos download can still continue. If second thread is show Tlable or tgauage or etc. your application will not freezing. you haveto do good organization thread's job
ZAGOR TENAY TÜRK'tür... TÜRK kalacak...
Zoru başarırım, İmkansız zaman alır
FreeMan 35.5

Soru sormaya üşenmiyorsan, sorunun çözümünü yazmaya da üşenme !!!
Kullanıcı avatarı
mia
Üye
Mesajlar: 239
Kayıt: 17 Nis 2015 02:18

Re: question about threading

Mesaj gönderen mia »

as example i have the following thread with help from mrmarman it should download images from web and save it to memory stream then load it to image object then add it in listview as item Then its should free the memory stream to repeat the process, it works perfect when its executed alone but if other thread run with it,, FMS does not freed successfully and starts to replaces images

Kod: Tümünü seç

type
  TURLDownload = class(TThread)
  private
    FListView    : TListView;
    FListViewIdx : Integer;
    FMs          : TMemoryStream;
    FURL         : String;
    procedure UpdateVisual;
    function  DownloadToStream: Boolean;
  protected
    procedure Execute; override;
  public
    property URL         : String read FURL write FURL;
    property ListView    : TListView read FListView write FListView;
    property ListViewIdx : Integer read FListViewIdx write FListViewIdx;
  end;

Procedure TFORM.Add_Item(strCaption: String; ListView : TListView; strFile: String; boolBlink : Boolean; strUniqueID:String; Currentstatus: string);
Var
  ResStream : TResourceStream;
begin
Currentstatus := Status;
aGif := TGifImage.Create;
ResStream  := TResourceStream.Create(HInstance, 'f1', RT_RCDATA);
aGIF.LoadFromStream( ResStream );
ResStream.Free;
if Strfile = '' then
begin
  With ListView.Items.Add do
  begin
    Caption   := '';
    SubItems.Add( strCaption );                   // subitem 0
    SubItems.AddObject( 'IMA', TObject( aGif ) ); // subitem 1
    if boolBlink
      then  SubItems.Add( 'blink' )               // subitem 2
      else  SubItems.Add( '' );                   // subitem 2
    SubItems.Add( strUniqueID );                  // subitem 3 // UniqueID
    SubItems.Add('-');                            // subitem 4 // Next User Idx (beside)
    SubItems.Add(Currentstatus);                            // subitem 5 // StateIdx
  end;
end else
begin
  With ListView.Items.Add do
  begin
    Caption   := '';
    SubItems.Add( strCaption ); // subitem 0
    SubItems.AddObject( 'IMA', TObject( aGif ) ); // subitem 1
    if boolBlink
      then  SubItems.Add( 'blink' ) // subitem 2
      else  SubItems.Add( '' );     // subitem 2
      SubItems.Add( strUniqueID );                  // subitem 3 // UniqueID
    SubItems.Add('-');                            // subitem 4 // Next User Idx (beside)
    SubItems.Add(Currentstatus);                              // subitem 5 // StateIdx
      With TURLDownload.Create(False) do
      begin
          URL             := strFile;
          ListView        := ListView1;
          ListViewIdx     := ListView1.Items.Count-1;
          Application.ProcessMessages;
        //Memo1.Lines.Add(' Image Download Thread...  @ThreadID = ' + IntToStr( ThreadID ) );
      end;
    end;
  end;
end;
 
 
  procedure TURLDownload.Execute;
begin
FMs := TMemoryStream.Create;
  if DownloadToStream
    then
    TThread.synchronize(nil, UpdateVisual);
    Sleep(100);
end;

procedure TURLDownload.UpdateVisual;
begin
  FMS.Position := 0;
  if ExtractFileExt(Furl) = '.gif' then  // if image is gif
  begin
    aGIF := TGifImage.Create;
    aGIF.LoadFromStream(FMS);
    aGIF.Transparent := True;
    FListView.Items[FListViewIdx].SubItems.Objects[1] := TObject(aGif);

  end;

    if ExtractFileExt(Furl) = '.jpg' then  // if image is gif
  begin
    jpg := TJPEGImage.Create;
    jpg.LoadFromStream(FMS);
    FListView.Items[FListViewIdx].SubItems.Objects[1] := TObject(jpg);

  end;

  if ExtractFileExt(Furl) = '.png' then  // if image is gif
  begin
    png := TPngImage.Create;
    png.LoadFromStream(FMS);
    FListView.Items[FListViewIdx].SubItems.Objects[1] := TObject(png);
  end;
    FMs.Free;
end;
بِسْمِ اللهِ الرَّحْمنِ الرَّحِيمِ
in god i trust with every movement i do
graduated student and looking for knowledge
Kullanıcı avatarı
Kuri_YJ
Moderator
Mesajlar: 2248
Kayıt: 06 Ağu 2003 12:07
Konum: İstanbul
İletişim:

Re: question about threading

Mesaj gönderen Kuri_YJ »

Selam,

Please research the Synchronisation in the threads. VCL objects must be synchronized. Here is the some examples.

http://edn.embarcadero.com/article/22411

http://delphi.about.com/od/kbthread/a/thread-gui.htm

http://delphi.about.com/od/kbthread/

https://sergworks.wordpress.com/2010/09 ... ead-class/

You can find other examples for Delphi Threading.

Bye..
Kuri Yalnız Jedi
Harbi Özgürlük İçin Pisi http://www.pisilinux.org/
Kullanıcı avatarı
mia
Üye
Mesajlar: 239
Kayıt: 17 Nis 2015 02:18

Re: question about threading

Mesaj gönderen mia »

selam , thank you for replay after deep search and investigate the problem not in the thread at all , current issue its in the code it self

problem accrued with placing icon to specif index look at the comment inside the code

Kod: Tümünü seç

With TURLDownload.Create(False) do
      begin
        FreeOnTerminate := True;
        URL             := strFile;
        ListView        := ListView1;
        ListViewIdx     := ListView1.Items.Count-1;//here listviewidx its variable inside the thread to define which item index will place the image to 
        Application.ProcessMessages;
      end;
also after thread execute here comes the more complex with update the item image

Kod: Tümünü seç

procedure TURLDownload.UpdateVisual;
begin
  FMS.Position := 0;
  if ExtractFileExt(Furl) = '.gif' then  // if image is gif
  begin
    aGIF := TGifImage.Create;
    aGIF.LoadFromStream(FMS);
    aGIF.Transparent := True;
    FListView.Items[FListViewIdx].SubItems.Objects[1] := TObject(aGif);//  here its place to right index and every thing is good tell now

  end;


now after place the right index iam trying to exchange items in some case matched like this

Kod: Tümünü seç

for i := 0 to ListView1.Items.Count-1
     do if ListView1.Items[i].SubItems[3] = IntToStr(UniqueID)
     then
     begin
     R:= listview1.Items[i].Index;
     ExchangeItems( ListView1, R, 0);
     end;

procedure ExchangeItems(lv: TListView; i, j: Integer);
var
  tempLI: TListItem;
begin
  lv.Items.BeginUpdate;
  try
    tempLI := TListItem.Create(lv.Items);
    tempLI.Assign(lv.Items.Item[i]);
    lv.Items.Item[i].Assign(lv.Items.Item[j]);
    lv.Items.Item[j].Assign(tempLI);
    tempLI.Free;
  finally
    lv.Items.EndUpdate
  end;
end;
after exchange the items image got replace because of false index i dont know how to solve this tell now .
بِسْمِ اللهِ الرَّحْمنِ الرَّحِيمِ
in god i trust with every movement i do
graduated student and looking for knowledge
Kullanıcı avatarı
Kuri_YJ
Moderator
Mesajlar: 2248
Kayıt: 06 Ağu 2003 12:07
Konum: İstanbul
İletişim:

Re: question about threading

Mesaj gönderen Kuri_YJ »

Selam,

I did not understand exactly what do you want. Could you explain what do you want to do finally? I want to see the job, may be there are different ways to solve your real issue.

Bye
Kuri Yalnız Jedi
Harbi Özgürlük İçin Pisi http://www.pisilinux.org/
Kullanıcı avatarı
mia
Üye
Mesajlar: 239
Kayıt: 17 Nis 2015 02:18

Re: question about threading

Mesaj gönderen mia »

selam , i will explain what is my project about

iam creating client application and try to store user names in list view , those client have image icon beside there names in the list view this part already implemented .

my only problem now trying to move usernames inside list view as example

-Kuri_YJ
-Mia
-anothername
------
i want to rearrange those names as example

-Mia
-Kuri_YJ
-anothername

thats why i use ExchangeItems procedure .

success process , items successful rearranged and every thing is good but only image of this items got replaced . i want to rearrange those items with there image and avoid image replacement
بِسْمِ اللهِ الرَّحْمنِ الرَّحِيمِ
in god i trust with every movement i do
graduated student and looking for knowledge
Kullanıcı avatarı
Kuri_YJ
Moderator
Mesajlar: 2248
Kayıt: 06 Ağu 2003 12:07
Konum: İstanbul
İletişim:

Re: question about threading

Mesaj gönderen Kuri_YJ »

:)

If you had problems with rearranging the Items in One List View, I think You Create another one, Insert Items (Sorted or changed order) then finally you assign new Created ListView to Old List view. This is the oanother way to Re arrange.

Or another different way, Delete Item from the list view and Insert New Item Listview.

Or when you try to replace images, take the OLD image to Memory (another Image Object), replace images with the new created Images.

But in the all those solutions, when you try to access Listview (for reading or writing) Use CriticalSection. In the Multi Threading application, you must LOCK and UNLOCK the objects when you try to access same objects in the different Threads.

These are my opinions (if I understand correctly).

Best Regards.
Kuri Yalnız Jedi
Harbi Özgürlük İçin Pisi http://www.pisilinux.org/
Kullanıcı avatarı
mia
Üye
Mesajlar: 239
Kayıt: 17 Nis 2015 02:18

Re: question about threading

Mesaj gönderen mia »

my client always send command to update list as following code read comments inside code

Kod: Tümünü seç

begin
  if ListView1.Selected <> nil
      then strSelectedUID := Listview1.Selected.SubItems[3]
      else strSelectedUID := '';
    listview1.Items.BeginUpdate;
    try
    ListView1.Items.Clear;//clear all items
finally
    listview1.Items.EndUpdate;
  end;
    if Assigned(MS) then
    begin
      SL := TStringList.Create;
      try
        SL.LoadFromStream(MS);
        for I := 0 to SL.Count -1  do
        begin
            Line := SL.Strings[I];
            usergetlist(Line, strName, strUniqueID, strChannel, icon);
            boolblink := True;
           Add_Item( strName, ListView1, icon, boolblink, strUniqueID, Status);// here to re add items
        end;
      finally
        SL.Free;
      end;
      MS.Free;
      if stream.Active = True then // if this condition meet do the following  exchange
      begin
       for i := 0 to ListView1.Items.Count-1
     do if ListView1.Items[i].SubItems[3] = IntToStr(UniqueID)
     then
     begin
     R:= listview1.Items[i].Index;
     ExchangeItems( ListView1, R, 0);
     end;
      end;

    if strSelectedUID <> '' then
      begin
        for i := 0 to ListView1.Items.Count-1
          do if ListView1.Items[i].SubItems[3] = strSelectedUID
            then Listview1.Items[i].Selected := True;
      end;
    end;
end;
and this is my add item code if you can see in code while thread created and there is variable called ListViewIdx to define item index to place image unfortunately its define to wrong index while exchange :(

Kod: Tümünü seç

Procedure TFORM.Add_Item( strCaption: String; ListView : TListView; strFile: String; boolBlink : Boolean; strUniqueID:String; Currentstatus: string);
Var
  ResStream : TResourceStream;
begin
Currentstatus := Status;
aGif := TGifImage.Create;
ResStream  := TResourceStream.Create(HInstance, 'f1', RT_RCDATA);
aGIF.LoadFromStream( ResStream );
ResStream.Free;
if Strfile = '' then
begin
  With ListView.Items.Add do
  begin
    Caption   := '';
    SubItems.Add( strCaption );                   // subitem 0
    SubItems.AddObject( 'IMA', TObject( aGif ) ); // subitem 1
    if boolBlink
      then  SubItems.Add( 'blink' )               // subitem 2
      else  SubItems.Add( '' );                   // subitem 2
    SubItems.Add( strUniqueID );                  // subitem 3 // UniqueID
    SubItems.Add('-');                            // subitem 4 // Next User Idx (beside)
    SubItems.Add(Currentstatus);                            // subitem 5 // StateIdx
  end;
end else
begin
  With ListView.Items.Add do
  begin
    Caption   := '';
    SubItems.Add( strCaption ); // subitem 0
    SubItems.AddObject( 'IMA', TObject( aGif ) ); // subitem 1
    if boolBlink
      then  SubItems.Add( 'blink' ) // subitem 2
      else  SubItems.Add( '' );     // subitem 2
      SubItems.Add( strUniqueID );                  // subitem 3 // UniqueID
    SubItems.Add('-');                            // subitem 4 // Next User Idx (beside)
    SubItems.Add(Currentstatus);                              // subitem 5 // StateIdx
      With TURLDownload.Create(False) do
      begin
        //Suspended       := True;
        FreeOnTerminate := True;
        URL             := strFile;
        ListView        := ListView1;
        ListViewIdx     := ListView1.Items.Count-1;
        Application.ProcessMessages;
        //Resume;
        //Memo1.Lines.Add(' Image Download Thread...  @ThreadID = ' + IntToStr( ThreadID ) );
      end;
    end;
  end;
end;
بِسْمِ اللهِ الرَّحْمنِ الرَّحِيمِ
in god i trust with every movement i do
graduated student and looking for knowledge
Kullanıcı avatarı
Kuri_YJ
Moderator
Mesajlar: 2248
Kayıt: 06 Ağu 2003 12:07
Konum: İstanbul
İletişim:

Re: question about threading

Mesaj gönderen Kuri_YJ »

Selam,

I think you must use CRITICAL SECTION in your code. When you touch the Listview in the code, you must enter the CriticalSection.

Because, when you access the Listview or ListViewIdx another Thread may changed the value. If you start a process Updating, exchanging, adding Item to Listview Idx may changed by another thread.

If it is possible, send your code to us, we will try your code on our machines to solve the problem. (I am not guranteed :) but I will loook)

Bye
Kuri Yalnız Jedi
Harbi Özgürlük İçin Pisi http://www.pisilinux.org/
Kullanıcı avatarı
mia
Üye
Mesajlar: 239
Kayıt: 17 Nis 2015 02:18

Re: question about threading

Mesaj gönderen mia »

project attached client and server , every thing implemented inside only problem with image while item exchange .
بِسْمِ اللهِ الرَّحْمنِ الرَّحِيمِ
in god i trust with every movement i do
graduated student and looking for knowledge
Kullanıcı avatarı
Kuri_YJ
Moderator
Mesajlar: 2248
Kayıt: 06 Ağu 2003 12:07
Konum: İstanbul
İletişim:

Re: question about threading

Mesaj gönderen Kuri_YJ »

Selam,

You must think on flow of your code. ExchangeItem calls twice.

Kod: Tümünü seç

procedure Ttestthreading.streamClick(Sender: TObject);
var
  i : integer;
begin
  if stream.Caption = 'stream' then
  begin
    for i := 0 to ListView1.Items.Count-1 do
    begin
      if ListView1.Items[i].SubItems[3] = IntToStr(UniqueID) then
      begin
        R := listview1.Items[i].Index;
      end;
      ExchangeItems( ListView1, R, 0); // HERE IS THE FIRST CALL
      stream.Caption := 'stopstream';
      SendCommandWithParams( TCPClient, 'Startstream', IntToStr(UniqueID) + Sep);
      istreaming := True;
      //start stream
    end ;
  end
  else
  if stream.Caption = 'stopstream' then
  begin
    ExchangeItems( ListView1, R, 0);
    stream.Caption := 'stream';
    //stopstream
    SendCommandWithParams( TCPClient, 'Stopstream', IntToStr(UniqueID) + Sep);
    istreaming := false;
  end;
end;

Kod: Tümünü seç

procedure Ttestthreading.whoistream;
var
i : integer;
begin
  for i := 0 to ListView1.Items.Count-1
    do if ListView1.Items[i].SubItems[3] = Trim(getid) then
  begin
   R:= listview1.Items[i].Index;
  end;
   ExchangeItems( ListView1, R, 0); // HERE IS THE SECOND CALL. WHY?????
end;
And why ExchangeItem not of the thread member?
Kuri Yalnız Jedi
Harbi Özgürlük İçin Pisi http://www.pisilinux.org/
Kullanıcı avatarı
mia
Üye
Mesajlar: 239
Kayıt: 17 Nis 2015 02:18

Re: question about threading

Mesaj gönderen mia »

i call exchange for the client it self while streaming because i dont call the list when client click to stream , calling exchangeitems inside the thread cause some errors , maybe you can give me better direction with coding
بِسْمِ اللهِ الرَّحْمنِ الرَّحِيمِ
in god i trust with every movement i do
graduated student and looking for knowledge
Kullanıcı avatarı
mia
Üye
Mesajlar: 239
Kayıt: 17 Nis 2015 02:18

Re: question about threading

Mesaj gönderen mia »

Kuri_YJ , Thank youuuuuuuuuuu you give me a light in my head , problem of image solved when called exchange items inside my download url thread .

to make my application better , de i have to remove exchangeitem from stream button and call it fro, the list instead ?
بِسْمِ اللهِ الرَّحْمنِ الرَّحِيمِ
in god i trust with every movement i do
graduated student and looking for knowledge
Kullanıcı avatarı
Kuri_YJ
Moderator
Mesajlar: 2248
Kayıt: 06 Ağu 2003 12:07
Konum: İstanbul
İletişim:

Re: question about threading

Mesaj gönderen Kuri_YJ »

Selam,

Uhm I do not understand your code exactly (and your programs subject) I can not give a suggestions to make your code better. Sorry :)

If you think, your new Idea is better, try it. Try and test it.

Bye,
Kuri Yalnız Jedi
Harbi Özgürlük İçin Pisi http://www.pisilinux.org/
Cevapla