2010-09-27 17 views
6

मैंने पहले कभी थ्रेड के साथ काम नहीं किया है, और अब मैं डेटाबेस स्थिति की जांच करने के लिए एक क्वेरी के साथ थ्रेड बनाने की कोशिश कर रहा हूं। क्वेरी निम्नानुसार है:धागे को लिखने और निष्पादित करने के लिए

select (*) as DBCount from v$datafile where status in 'OFFLINE';

यह क्वेरी ऑफ़लाइन होने वाले सभी डेटाबेस की कुल संख्या देता है। अब मैं डेल्फी में एक थ्रेड बनाना चाहता हूं जो इस क्वेरी को मेरे एप्लिकेशन की पृष्ठभूमि में निष्पादित करेगा जब मैं इसे चलाऊंगा और परिणाम लेबल पर प्रदर्शित करूंगा।

+0

मैंने पर्थ्रेड टैग को हटा दिया क्योंकि डेल्फी टैग के साथ वास्तव में संगत नहीं है। – mghie

उत्तर

0

डेल्फी में TThread कक्षा है। आप डेल्फी आईडीई (टर्बो डेल्फी में: फ़ाइल-> नई-> डेल्फी प्रोजेक्ट्स-> डेल्फी फाइल-> थ्रेड ओबजेट) से सरल विज़ार्ड का उपयोग करके ऐसे धागे बना सकते हैं। इसके कन्स्ट्रक्टर में डेटाबेस से कनेक्शन बनाते हैं, और Execute विधि में आप लूप बना सकते हैं जो क्वेरी डेटाबेस है, कुछ वैश्विक चर अद्यतन करें (threadvar के रूप में घोषित नहीं किया गया) और कुछ समय सोएं।

+2

परिणाम को 'थ्रेडवर' में डालकर परिणामस्वरूप किसी अन्य थ्रेड के लिए असंभव हो जाएगा। यह कैसे उपयोगी होगा? – mghie

+1

अप्स, क्षमा करें, मेरी गलती, निश्चित रूप से यह सामान्य चर होना चाहिए। –

+0

बस सोच रहा है कि यह जवाब क्यों कम किया गया है (थ्रेडवर के बावजूद भी) क्योंकि मुझे लगता है कि यह सहायक है और ओपी को शुरू करने और पढ़ने के लिए एक जगह देता है। यह बहुत अच्छा होगा अगर एसओ को केवल प्रेरित डाउनवोट के लिए अनुमति दी गई ... – Remko

7

मल्टीथ्रेडिंग कठिन है। AsyncCalls जैसे साधारण थ्रेडिंग फ्रेमवर्क का उपयोग करके आप बेहतर हो सकते हैं।

Delphi - Threading frameworks

How Do I Choose Between the Various Ways to do Threading in Delphi?

Delphi thread that waits for data, processes it, then resumes waiting

+0

एक और अच्छा थ्रेडिंग फ्रेमवर्क gabr की OmniThreadLibrary है: पी http://otl.17slon.com/ – Remko

+0

@Remko: यह उन धागे में शामिल है जिन्हें मैं रेफर कर रहा था। – gabr

0

यहाँ आप डेटाबेस पर धागे का उपयोग कर के बारे में चर्चा पा सकते हैं:

बाद StackOverlow धागे आप कैसे अपनी समस्या को हल करने के लिए के बारे में अधिक जानकारी दे सकते हैं।

Simple Thread Sample Delphi

कुछ कोड है कि आप के लिए उपयोगी हो सकता है कर रहे हैं।

सम्मान।

1

असिनकॉल का उपयोग करना काफी आसान है। के (सभी त्रुटि हैंडलिंग अनदेखी) अपनी गैर-थ्रेडेड कोड इस तरह दिखता है मान लेते हैं:

Query := 'select (*) as DBCount from...'; 
ExecuteSQL(SqlConnection,Query); 
SqlResult := GetSqlResult(SqlConnection); 
SqlRow := GetSqlRow(SqlResult); 
MyLabel.Text := SqlRow[0]; 
...Go on to do other things... 

कहाँ दूसरी पंक्ति (सर्वर उत्तर देने के लिए के लिए इंतज़ार कर) ब्लॉक कर रहा है। आपका नया कोड इस तरह दिखेगा:

uses AsyncCalls;  //added to your existing uses statement 
... 
procedure DoesSomething(); 
var Thread: TAsyncCall;    //your interface to AsyncCalls 
    procedure AsyncSqlCall();    //this is a LOCAL procedure 
    Query := 'select (*) as DBCount from...'; 
    ExecuteSQL(SqlConnection,Query); 
    SqlResult := GetSqlResult(SqlConnection); 
    SqlRow := GetSqlRow(SqlResult); 
    EnterMainThread; 
    try 
     Assert(GetCurrentThreadId = MainThreadId); 
     MyLabel.Text := SqlRow[0]; 
    finally 
     LeaveMainThread;   
    end; 

begin       //this begins proc DoSomething() 
    ... 
    Thread := LocalAsyncCall(@AsyncSqlCall); 
    ...Go on to do other things... 
end; 

सभी हम किया है एक स्थानीय proc में अवरुद्ध एसक्यूएल कॉल डाल दिया और, एक और धागा में यह निष्पादित करने के लिए, जबकि मुख्य थ्रेड क्रियान्वित जारी AsyncCalls बताया है। एकमात्र मुश्किल हिस्सा वीसीएल का उपयोग कर रहा था, जो थ्रेड-सुरक्षित नहीं है। तो मैंने उस रेखा को मुख्य धागे में सुरक्षित रूप से चलाया था।

कुछ बिंदु पर आप वाकई Async धागा पूरा कर लिया है करने की आवश्यकता है, तो आप मुख्य थ्रेड ब्लॉक करने के लिए इस लाइन पर अमल होगा जब तक AsyncSqlCall समाप्त हो जाता है:

Thread.sync; 

यहाँ वास्तव में अच्छी बात यह है है कि AsyncCalls सब संभालती है थ्रेड पूल बनाने, थ्रेड बनाने आदि के बारे में सामान, हालांकि इस उदाहरण में नहीं दिखाया गया है, आप अपने धागे में वेरिएबल पास कर सकते हैं, और एक मान वापस कर सकते हैं। आपको स्थानीय प्रो का उपयोग करने की ज़रूरत नहीं है, लेकिन ऐसा करने से यह सभी स्थानीय वार्स तक पहुंच प्रदान करता है। आप यह सब वैश्विक बना सकते हैं, और फिर एक दिनचर्या में Async थ्रेड लॉन्च कर सकते हैं, और दूसरे में इसके पूरा होने के लिए परीक्षण कर सकते हैं।

प्रतिबंध:

आपका Async धागा स्पर्श नहीं करना चाहिए (पढ़ना या लिखना) कुछ भी लेकिन अपने स्वयं के चर, और अपने मुख्य थ्रेड उन्हें छू नहीं चाहिए, जबकि Async धागा चल रहा है। आपको इसे इस तरह से कोड करना होगा। कुल अराजकता बनाने से आपको कुछ भी नहीं रोकेगा। उपर्युक्त उदाहरण में, आपका मुख्य धागा क्वेरी, एसक्यूएलकनेक्शन, एसक्लरसल्ट, और एसक्लरो को स्पर्श नहीं करना चाहिए। यदि आपके कोड का कोई भी हिस्सा Thread.sync कॉल से पहले उन वर्रों में से एक का उपयोग करता है, तो आपका कोड काम करेगा - लेकिन अजीब स्थानों में अपवाद फेंक दें जिन्हें आपने कभी उम्मीद नहीं की थी। तो इसे सरल रखें।

आपके असिंक थ्रेड को वीसीएल का उपयोग नहीं करना चाहिए। उपरोक्त नमूना इस सीमा के आस-पास सुरक्षित रूप से पहुंचने के कई तरीकों में से एक दिखाता है।

अंत:

AsyncCalls एक पूर्ण बहु-थ्रेडिंग ढांचा नहीं है। यह procs & कार्यों को असीमित रूप से कॉल करने का एक तरीका है (यानी बिना प्रतीक्षा के)। इसे बहुत दूर धक्का देने की कोशिश न करें - जिसका मेरा मतलब है, इसे पूरी तरह से मल्टीटास्किंग प्रोग्राम का आधार बनाने की कोशिश न करें।

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