के साथ काम करना सबसे पहले, मैं जावा प्रोग्रामर हूं और मैं सी # पर नया हूं और मुझे सी # डेवलपर्स की राय चाहिए। मैं डेटाबेस (फायरबर्ड 1.5) से कनेक्ट होने वाला एक एप्लीकेशन विकसित कर रहा हूं, कुछ डेटा पूछता हूं और वापस लौटाता हूं इसलिए जटिल होने के लिए कुछ भी नहीं है लेकिन दुर्भाग्यवश मैं कुछ चीजों में फंस गया हूं:सर्वोत्तम व्यवहार: सी # डीबी
जैसा कि हम जानते हैं कि डेटाबेस कनेक्शन होना चाहिए अलग थ्रेड में एहसास हुआ क्योंकि यह एक उच्च वजन वाला ऑपरेशन है और सभी कनेक्शन पहले से ही खोले गए कनेक्शन का पुन: उपयोग करने के लिए कनेक्शन पूल में होना चाहिए, बल्कि नया बनाएं।
तो मेरा पहला प्रश्न - कनेक्शन पूल को व्यवस्थित तरीके से व्यवस्थित करने के लिए यहां जाएं? (क्या कनेक्शन पूल के बारे में मैं पढ़ा है कि आम तौर पर कनेक्शन पूल पहले से ही डेटा प्रदाताओं ने महसूस किया है और मैं बस किसी न किसी प्रकार कनेक्शन parametres में सेट कर सकते हैं "connectionBuilder.Pooling सच =," की तरह)
क्या प्रश्नों के बारे में? मेरा मतलब है कि मैंने हमेशा एक क्वेरी प्रति थ्रेड का उपयोग किया है (और मुझे लगता है कि यह सही कारण है कि हम एक हाईवेट ऑपरेशन भी करते हैं, क्या मैं गलत हूं? वैसे भी मुझे डेटाबेस काम व्यवस्थित करने के साथ आपके सर्वोत्तम अभ्यास देखने में खुशी होगी) जावा में मैं सिर्फ प्रयोग के द्वारा अलग थ्रेड से क्वेरी परिणाम लौटने एक इंटरफेस और गुमनाम वर्गों इस तरह कार्य करें:
DBHelper.class में
public interface QueryListener {
public void onSuccess(ArrayList<?>);
public void onError(Exception e);
}
public synchronized void getPromoActions(final QueryListener listener) {
if (listener != null) {
try {
ArrayList<String> myPromoActions;
.............
// some query's code
.....
listener.onSucces(myPromoActions);
} catch(Exception e) {
listener.onError(e);
} finally {
closeDatabase();
}
}
}
कुछ में
(DBHelper एक सिंगलटन है) यूआई-श्रेणी (eaxample MainWindow के लिए)
public void getPromoActions(){
new Thread(new Runnable() {
@Override
public void run() {
DBHelper.getInstance().getPromoActions(new QueryListener() {
@Override
public void onSuccess(ArrayList<?>) {
// set Data to UI element such as Table
}
@Override
public void onError(Exception e){
// Handling exception
}
});
}
}).start();
}
सी # में मैं चिह्नित करने के लिए कौन सी विधि सूत्र में निष्पादित करेंगे प्रतिनिधियों का उपयोग करना चाहिए, लेकिन unfortionally मैं पैरामीटर के रूप में किसी भी कॉलबैक नहीं भेज सकते हैं - तो कैसे मैं अपने क्वेरी लौटना चाहिए मुख्य यूआई थ्रेड के परिणाम?
युपीडी
मैं थोड़ा कैसे प्रतिनिधियों और घटनाओं के साथ काम करने के लिए समझ में है, लेकिन एक कस्टम घटना को ऊपर उठाने के साथ एक समस्या है।
private QueryResultEventHandler _queryResult;
public event QueryResultEventHandler onQueryResult
{
add
{
lock (this)
{
_queryResult += value;
}
}
remove
{
lock (this)
{
_queryResult -= value;
}
}
}
में यूआई वर्ग (MainWindow) मैं का उपयोग करें:
public delegate void QueryResultEventHandler(object sender, QueryResultEventArgs e);
public class QueryResultEventArgs : EventArgs
{
public List<String> QueryResult { get; set; }
public int QueryRecordsCount { get; set; }
}
और मेरे DBHelper.class में मैं एक अगले क्षेत्र और घटना की घोषणा की: मैं एक eventhandler और एक कस्टम EventArgs की घोषणा की थी अगला कोड:
public void GetAllDistricts() {
DBHelper.Instance.onQueryResult += new QueryResultEventHandler(GetAllDistricsResultHandler);
DBHelper.Instance.GetAllDistricts();
}
public void GetAllDistricsResultHandler(object sender, QueryResultEventArgs e){
// Here I'm adding the query result to Table
}
तो मेरी समस्या अब एक घटना को असंकालिक रूप से कैसे विकसित करना है? मेरे DBHelper.class मैं startInvoke & _query प्रतिनिधि के साथ endInvoke का उपयोग करने की कोशिश कर रहा हूं, लेकिन ऐसा लगता है कि मुझे कुछ कोड लाइनों को याद आया था जो मैं समझ नहीं पाया था कि मैं क्या कर रहा हूं कि घटना को कैसे बढ़ाया जाए असीमित रूप से? यहां मेरा डीबीहेल्पर।वर्ग कोड:
public void GetAllDistricts() {
try
{
if (_queryResult != null)
{
//** This code should run asynchronously ---------->
using (FbConnection connection = GetConnection())
{
FbCommand getAllDistrictsCommand = new FbCommand();
getAllDistrictsCommand.CommandText = "SELECT * FROM SEND";
getAllDistrictsCommand.Connection = connection;
QueryResultEventArgs args = new QueryResultEventArgs();
using (FbDataReader reader = getAllDistrictsCommand.ExecuteReader())
{
while (reader.Read())
{
//Here must be the processing of query results and filling the
//QueryResultEventArgs
args.QueryResult.Add(reader[0].ToString());
}
args.QueryRecordsCount = reader.GetInt32(reader.GetOrdinal("Rows"));
// And here after sucessfull query I should call OnQueryResult()
OnQueryResult(args);
}
}
//**<--------------------
}
else
{
throw new Exception("...Some exception message...");
}
}
catch (Exception e)
{
log.ErrorException(e.Message, e);
throw new Exception("...Some exception message...");;
}
finally {
CloseConnection();
}
}
// The QueryResultEvent method
protected void OnQueryResult(QueryResultEventArgs e)
{
if (_queryResult != null)
{
_queryResult(this, e);
}
}
डेटाबेस कनेक्शन पूलिंग केवल तभी फायदेमंद होगा यदि आप आर्किटेक्चर इसे अनुमति देते हैं। यदि आप क्लाइंट सर्वर प्रकार का अनुप्रयोग विकसित कर रहे हैं यानी एक फ्रंट एंड जो सीधे सर्वर से कनेक्ट होता है तो कनेक्शन पूलिंग बिंदु को याद करने की तरह है। क्या आप सीधे क्लाइंट एप्लिकेशन से डेटाबेस से कनेक्ट कर रहे हैं। – Namphibian
@Namphibian हां, मैं क्लाइंट-सर्वर प्रकार का अनुप्रयोग विकसित कर रहा हूं और सीधे डेटाबेस से कनेक्ट कर रहा हूं। – whizzzkey
आपके मामले में एक कनेक्शन पूल जोड़ने में जटिलता और कोई लाभ नहीं जोड़ रहा है। आम तौर पर एक कनेक्शन पूल एक आवेदन सर्वर पर होगा। कनेक्शन पूलिंग के लाभों का लाभ उठाने के लिए आपको एन-स्तरीय आर्किटेक्चर में स्थानांतरित करने की आवश्यकता होगी। – Namphibian