2012-03-30 14 views
6

अगर मैं इसे निष्पादित करता हूं तो मेरा एप्लिकेशन तब तक जवाब नहीं देगा जब तक कि सभी फाइलें और उन्हें सूची बॉक्स पर नहीं मिल जाए, मेरा सवाल यह है कि मैं इस कार्य को अनपेक्षित स्थिति से बचने के लिए बहु थ्रेड कैसे कर सकता हूं! मैं अभी भी डेल्फी novoiceडेल्फी फ़ाइल खोज मल्टीथ्रेडिंग

procedure TfrMain.FileSearch(const PathName, FileName : string; txtToSearch : string; const InDir : boolean); 
var Rec : TSearchRec; 
    Path : string; 
    txt : string; 
    fh : TextFile; 
    i : integer; 
begin 


Path := IncludeTrailingBackslash(PathName); 
if FindFirst(Path + FileName, faAnyFile - faDirectory, Rec) = 0 then 
try 
    repeat 

    AssignFile(fh, Path + Rec.Name); 
    Reset(fh); 
    Readln(fh,txt); 

    if ContainsStr(txt, txtToSearch) then 
     ListBox1.Items.Add(Path + Rec.Name); 

    until FindNext(Rec) <> 0; 
finally 
    FindClose(Rec); 

end; 

If not InDir then Exit; 

if FindFirst(Path + '*.*', faDirectory, Rec) = 0 then 
try 
    repeat 
    if ((Rec.Attr and faDirectory) <> 0) and (Rec.Name<>'.') and (Rec.Name<>'..') then 
    FileSearch(Path + Rec.Name, FileName, txtToSearch, True); 
    until FindNext(Rec) <> 0; 
finally 
    FindClose(Rec); 
end; 
end; 

उत्तर

5

Here आप पृष्ठभूमि फ़ाइल OmniThreadLibrary के साथ लागू स्कैनर बारे में एक लेख पा सकते हैं हूँ।

5

आप एक धागा में फ़ाइल स्कैनिंग सामान रख सकते हैं और whenver काम मुख्य रूप है, जो तब सूची बॉक्स अद्यतन करता है करने के लिए एक विंडोज़ संदेश भेजने के समाप्त हो गया है (कोड का परीक्षण नहीं, छद्म कोड के रूप में यह लेने के लिए):

const 
    WM_FILESEARCH_FINISHED = WM_USER + 1; 

TFileSearchThread = class (TThread) 
private 
    FPath  : String; 
    FFileNames : TStringList; 
protected 
    procedure Execute; override; 
public 
    constructor Create (const Path : String); 
    destructor Destroy; override; 
    property FileNames : TStrings read FFileNames; 
end; 

constructor TFileSearchThread.Create (const Path : String); 
begin 
    inherited Create (True); 
    FPath := Path; 
    FFileNames := TStringList.Create; 
end; 

destructor TFileSearchThread.Destroy; 
begin 
    FreeAndNil (FFileNames); 
    inherited; 
end; 

procedure TFileSearchThread.Execute; 
begin 
    // do your file search here, adding each file to FFileNames 
    PostMessage (MainForm.Handle, WM_FILESEARCH_FINISHED, 0, 0); 
end; 

आप इस तरह इसका इस्तेमाल कर सकते हैं:

Thead := TFileSearchThread.Create (Path); 
Thread.Start; 

और मुख्य रूप इस प्रकार का संदेश हैंडलर होगा:

type 
    TMainForm = class(TForm) 
    ListBox1: TListBox; 
    private 
    procedure WMFileSearchFinished (var Msg : TMessage); message WM_FILESEARCH_FINISHED; 
    public 
    { Public declarations } 
    end; 

implementation 

procedure TMainForm.WMFileSearchFinished (var Msg : TMessage); 
begin 
    ListBox1.Items.AddStrings (Thread.FileNames); 
end; 
+1

+1, सरल, साफ समाधान। इतना गलत नहीं जा सकता है। –

+0

'पोस्टमेसेज (मेनफॉर्म.हैंडल, WM_FILESEARCH_FINISHED, 0, 0) नहीं होना चाहिए; 'सिंक्रनाइज़' के साथ उपयोग किया जा सकता है? – kobik

+1

@ कोबिक, चिंता करने की कोई आवश्यकता नहीं है, 'हैंडल' संपत्ति केवल पढ़ी जाती है और इसकी पढ़ाई परमाणु है। और इसे 0 से अलग होना चाहिए (नियंत्रण मर जाएगा और कोई संदेश नहीं मिल सका), इस प्रकार गेटटर कभी भी 'CreateHandle' नहीं करेगा जब यह हैडल 0 होता है। जोखिम ऑब्जेक्ट उदाहरण है, यदि आप 'मेनफॉर्म' को नष्ट करें और इसे एक्सेस करने का प्रयास करें, आप आम तौर पर एवी प्राप्त करेंगे। और, एम्बा ['उपयोग '] (http://edn.embarcadero.com/article/22411) यह भी :-) – TLama

संबंधित मुद्दे