मुझे लगता है कि काम करने के लिए थ्रेड-पूल थ्रेड का उपयोग करना आपका सबसे अच्छा समाधान है।
- अपने धागा समारोह पूरा करता है जब, धागा स्वचालित रूप से वापस लौट एक फ़ाइल
GetFileAttributes
पूरा होने से रन
- अपने फ़ॉर्म पर वापस पोस्ट परिणाम जाने की विशेषताओं क्वेरी करने के लिए काम की एक इकाई आवंटित पूल में (इसे मारने की कोई ज़रूरत नहीं है)
थ्रेड पूल का उपयोग करके आप नए धागे बनाने की लागत को बचाते हैं।
और आप उनसे छुटकारा पाने की कोशिश करने के दुख को बचाते हैं।
TGetFileAttributesData = class(TObject)
public
Filename: string;
WndParent: HWND;
Attributes: DWORD;
constructor Create(Filename: string; WndParent: HWND);
end;
:
RunInThreadPoolThread(
GetFileAttributesThreadMethod,
TGetFileAttributesData.Create('D:\temp\foo.xml', Self.Handle),
WT_EXECUTEDEFAULT);
आप धागा डेटा जानकारी धारण करने के लिए वस्तु बनाने:
तो फिर आप अपने काम सहायक विधि है कि QueueUserWorkItem
का उपयोग कर एक धागा पूल धागे पर एक वस्तु की विधि प्रक्रिया चलाता है
procedure TForm1.GetFileAttributesThreadMethod(Data: Pointer);
var
fi: TGetFileAttributesData;
begin
fi := TObject(Data) as TGetFileAttributesData;
if fi = nil then
Exit;
fi.attributes := GetFileAttributes(PWideChar(fi.Filename));
PostMessage(fi.WndParent, WM_GetFileAttributesComplete, NativeUInt(Data), 0);
end;
टी:
और आप अपने धागा कॉलबैक विधि बनाने मुर्गी तुम सिर्फ संदेश संभाल:
procedure WMGetFileAttributesComplete(var Msg: TMessage); message WM_GetFileAttributesComplete;
procedure TfrmMain.WMGetFileAttributesComplete(var Msg: TMessage);
var
fi: TGetFileAttributesData;
begin
fi := TObject(Pointer(Msg.WParam)) as TGetFileAttributesData;
try
ShowMessage(Format('Attributes of "%s": %.8x', [fi.Filename, fi.attributes]));
finally
fi.Free;
end;
end;
जादुई RunInThreadPoolThread
आप एक सूत्र में एक उदाहरण विधि पर अमल देता है कि फुलाना की सिर्फ एक सा है:
सिर्फ एक आवरण आप एक पर विधि कॉल करने देता है कौन सा उदाहरण चर:
TThreadMethod = procedure (Data: Pointer) of object;
TThreadPoolCallbackContext = class(TObject)
public
ThreadMethod: TThreadMethod;
Context: Pointer;
end;
function ThreadPoolCallbackFunction(Parameter: Pointer): Integer; stdcall;
var
tpContext: TThreadPoolCallbackContext;
begin
try
tpContext := TObject(Parameter) as TThreadPoolCallbackContext;
except
Result := -1;
Exit;
end;
try
tpContext.ThreadMethod(tpContext.Context);
finally
try
tpContext.Free;
except
end;
end;
Result := 0;
end;
function RunInThreadPoolThread(const ThreadMethod: TThreadMethod; const Data: Pointer; Flags: ULONG): BOOL;
var
tpContext: TThreadPoolCallbackContext;
begin
{
Unless you know differently, the flag you want to use is 0 (WT_EXECUTEDEFAULT).
If your callback might run for a while you can pass the WT_ExecuteLongFunction flag.
Sure, I'm supposed to pass WT_EXECUTELONGFUNCTION if my function takes a long time, but how long is long?
http://blogs.msdn.com/b/oldnewthing/archive/2011/12/09/10245808.aspx
WT_EXECUTEDEFAULT (0):
By default, the callback function is queued to a non-I/O worker thread.
The callback function is queued to a thread that uses I/O completion ports, which means they cannot perform
an alertable wait. Therefore, if I/O completes and generates an APC, the APC might wait indefinitely because
there is no guarantee that the thread will enter an alertable wait state after the callback completes.
WT_EXECUTELONGFUNCTION (0x00000010):
The callback function can perform a long wait. This flag helps the system to decide if it should create a new thread.
WT_EXECUTEINPERSISTENTTHREAD (0x00000080)
The callback function is queued to a thread that never terminates.
It does not guarantee that the same thread is used each time. This flag should be used only for short tasks
or it could affect other timer operations.
This flag must be set if the thread calls functions that use APCs.
For more information, see Asynchronous Procedure Calls.
Note that currently no worker thread is truly persistent, although worker threads do not terminate if there
are any pending I/O requests.
}
tpContext := TThreadPoolCallbackContext.Create;
tpContext.ThreadMethod := ThreadMethod;
tpContext.Context := Data;
Result := QueueUserWorkItem(ThreadPoolCallbackFunction, tpContext, Flags);
end;
पाठक के लिए व्यायाम: GetFileAttributesData
उद्देश्य यह है कि वें बताता अंदर एक रद्द झंडा बनाएं ई धागा कि यह को डेटा ऑब्जेक्ट को मुक्त करना होगा और अभिभावक को संदेश पोस्ट करना होगा।
यह सब कह रही है कि आप बना रहे हैं की एक लंबा रास्ता है:
DWORD WINAPI GetFileAttributes(
_In_ LPCTSTR lpFileName,
_Inout_ LPOVERLAPPED lpOverlapped,
_In_ LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);
नहीं कर सकते अतुल्यकालिक मॉडल को छोड़कर किसी भी बात के बारे में सोच। –
अन्य परिस्थितियों में, मैंने साझा फ़ाइलों की सेवा के लिए न्यूनतम-वेब सर्वर को तैनात करके इस समस्या को हल किया है, क्योंकि एक HTTP अनुरोध आसानी से रद्द/समय-समय पर रद्द किया जा सकता है। लेकिन इस मामले में, यह विभिन्न कारणों (तैनाती सिरदर्द, सुरक्षा मुद्दों इत्यादि) के लिए कोई समाधान नहीं है। –