2011-06-16 10 views
6

क्या यह संभव है और एक थ्रेड से CopyFileEx और CopyCallback/ProgressRoutine फ़ंक्शन (प्रोग्रेसबार। स्थिति सिंक्रनाइज़ किया जाएगा) को कॉल करने का अधिकार है?क्या CopyFileEx को द्वितीयक धागे से बुलाया जा सकता है?

क्या मैं एक थ्रेड में CopyCallback/ProgressRoutine फ़ंक्शन घोषित कर सकता हूं? मुझे त्रुटि मिलती है: @ProgressRoutine पर CopyFileEx में "परिवर्तनीय आवश्यक"।

उत्तर

12

बेशक यह संभव है। कॉलबैक फ़ंक्शन को थ्रेड के संदर्भ में बुलाया जाएगा जो CopyFileEx पर कॉल करता है। यदि आपको कुछ UI आदेशों को सिंक्रनाइज़ करने की आवश्यकता है, तो डेल्फी के सामान्य TThread.Synchronize, या जो भी अन्य इंटर-थ्रेड सिंक्रनाइज़ेशन तकनीक आप चाहते हैं उसका उपयोग करें।

कॉलबैक फ़ंक्शन थ्रेड क्लास का तरीका नहीं हो सकता है। इसे एपीआई द्वारा निर्धारित हस्ताक्षर से मेल खाना जरूरी है, इसलिए इसे एक स्टैंडअलोन फ़ंक्शन होना चाहिए। जब आपने इसे सही तरीके से घोषित कर दिया है, तो आपको @ ऑपरेटर का उपयोग करने की आवश्यकता नहीं होगी जब आप इसे CopyFileEx पर भेज दें।

function CopyProgressRoutine(TotalFileSize, TotalBytesTransferred: Int64; 
    StreamSize, StreamBytesTransferred: Int64; 
    dwStreamNumber, dwCallbackReason: DWord; 
    hSourceFile, hDestinationFile: THandle; 
    lpData: Pointer): DWord; stdcall; 

आप lpData पैरामीटर के साथ जुड़े धागा वस्तु को कॉलबैक फ़ंक्शन पहुंच सकते हैं। उस पैरामीटर के लिए धागा ऑब्जेक्ट के संदर्भ दर्रा जब आप CopyFileEx फोन:

procedure TCopyThread.Execute; 
begin 
    ... 
    CopyResult := CopyFileEx(CurrentName, NewName, CopyProgressRoutine, Self, 
    @Cancel, CopyFlags); 
    ... 
end; 

धागा वस्तु का उपयोग करने के साथ, आप उस वस्तु पर तरीकों फोन अपने आप ही प्रगति दिनचर्या सहित सकते हैं, तो निम्न सम्पूर्णता का गठन कर सकता है स्टैंडअलोन फ़ंक्शन का। यह सब कुछ आपके ऑब्जेक्ट की विधि पर वापस भेज सकता है। यहां मैंने मान लिया है कि विधि में स्टैंडअलोन फ़ंक्शन के समान पैरामीटर हैं, सिवाय इसके कि यह lpData पैरामीटर को छोड़ देता है क्योंकि यह Self पैरामीटर के रूप में पूरी तरह से पारित होने जा रहा है।

function CopyProgressRoutine; 
var 
    CopyThread: TCopyThread; 
begin 
    CopyThread := lpData; 
    Result := CopyThread.ProgressRoutine(TotalSize, TotalBytesTransferred, 
    StreamSize, StreamBytesTransferred, dwStreamNumber, 
    dwCallbackReason, hSourceFile, hDestinationFile); 
end; 
+0

'TProgressBar.Position' को सेट करने के लिए 'TThread.Synchronize' IMO की आवश्यकता नहीं है। 'TProgressBar.SetPosition' विधि कभी भी नियंत्रण के हैंडल को आवंटित नहीं करती है और 'SendMessage' कॉल के माध्यम से काम करती है जो थ्रेड संदर्भ को स्वयं ही स्विच करती है। – kludg

+7

तकनीकी रूप से, @ सर्ग, दौड़ की स्थिति है। 'हैंडल' संपत्ति पढ़ने से पहले 'TProgressBar'' हैंडल आवंटित 'चेक करता है। यदि हैंडल पहले ही आवंटित किया गया था, लेकिन 'हैंडल' पढ़ने से पहले इसे नष्ट कर दिया जाता है, तो हैंडल गलत थ्रेड में फिर से आवंटित किया जाएगा। ऐसा होने की संभावना नहीं है, इसलिए 'टीप्रेशंसबार' शायद सुरक्षित है। सामान्य रूप से, हालांकि, यूआई अपडेट यूआई थ्रेड के साथ सिंक्रनाइज़ होना चाहिए। –

+0

क्या मैं एक थ्रेड में CopyCallback/ProgressRoutine फ़ंक्शन घोषित कर सकता हूं? मुझे त्रुटि मिलती है: @ProgressRoutine पर CopyFileEx में "परिवर्तनीय आवश्यक"। – maxfax

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

  • कोई संबंधित समस्या नहीं^_^