मेरी वर्तमान प्रोजेक्ट में उपयोग के लिए मैंने एक कक्षा बनाई है जो मुझे SQL सर्वर async को कॉल करने की अनुमति देती है।लेनदेन में एकाधिक SQL सर्वर संग्रहीत प्रक्रियाओं को कॉल करें
मेरे कोड इस तरह दिखता है:
internal class CommandAndCallback<TCallback, TError>
{
public SqlCommand Sql { get; set; }
public TCallback Callback { get; set; }
public TError Error { get; set; }
}
class MyCodes:SingletonBase<MyCodes>
{
private static string _connString = @"Data Source=MyDB;Initial Catalog=ED;Integrated Security=True;Asynchronous Processing=true;Connection Timeout=0;Application Name=TEST";
private MyCodes() { }
public void SetSystem(bool production)
{
_connString =
string.Format(@"Data Source=MyDB;Initial Catalog={0};Integrated Security=True;Asynchronous Processing=true;Connection Timeout=0;Application Name=TEST", production ? "ED" : "TEST_ED");
}
public void Add(string newCode, Action<int> callback, Action<string> error)
{
var conn = new SqlConnection(_connString);
SqlCommand cmd = conn.CreateCommand();
cmd.CommandTimeout = 0;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = @"ADD_CODE";
cmd.Parameters.Add("@NEW", SqlDbType.NVarChar).Value = newCode;
cmd.Parameters.Add("@NewId", SqlDbType.Int).Direction = ParameterDirection.Output;
try
{
cmd.Connection.Open();
}
catch (Exception ex)
{
error(ex.ToString());
return;
}
var ar = new CommandAndCallback<Action<int>, Action<string>> { Callback = callback, Error = error, Sql = cmd };
cmd.BeginExecuteReader(Add_Handler, ar, CommandBehavior.CloseConnection);
}
private static void Add_Handler(IAsyncResult result)
{
var ar = (CommandAndCallback<Action<int>, Action<string>>)result.AsyncState;
if (result.IsCompleted)
{
try
{
ar.Sql.EndExecuteReader(result);
ar.Callback(Convert.ToInt32(ar.Sql.Parameters["@NewId"].Value));
}
catch (Exception ex)
{
ar.Error(ex.Message);
}
}
else
{
ar.Error("Error executing SQL");
}
}
public void Update(int codeId, string newCode, Action callback, Action<string> error)
{
var conn = new SqlConnection(_connString);
SqlCommand cmd = conn.CreateCommand();
cmd.CommandTimeout = 0;
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = @"UPDATE_CODE";
cmd.Parameters.Add("@CODE_ID", SqlDbType.Int).Value = codeId;
cmd.Parameters.Add("@NEW", SqlDbType.NVarChar).Value = newCode;
try
{
cmd.Connection.Open();
}
catch (Exception ex)
{
error(ex.ToString());
return;
}
var ar = new CommandAndCallback<Action, Action<string>> { Callback = callback, Error = error, Sql = cmd };
cmd.BeginExecuteReader(Update_Handler, ar, CommandBehavior.CloseConnection);
}
private static void Update_Handler(IAsyncResult result)
{
var ar = (CommandAndCallback<Action, Action<string>>)result.AsyncState;
if (result.IsCompleted)
{
try
{
ar.Sql.EndExecuteReader(result);
ar.Callback();
}
catch (Exception ex)
{
ar.Error(ex.Message);
}
}
else
{
ar.Error("Error executing SQL");
}
}
}
इस कोड का बहुत अधिक की तरह लग रहे हो सकता है, लेकिन यह मुझे के रूप में तो यह फोन कर सकते हैं:
private void Add_Click(object sender, EventArgs e)
{
MyCodes.Instance.Add("Test",Success,Error)
}
private void Success(int newId)
{
MessageBox.Show(newId.ToString(), "Success", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
private void Error(string error)
{
MessageBox.Show(error, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
कोड से ऊपर मेरे लिए बस ठीक काम करता है, मैं हर कॉल async करने में सक्षम हूँ।
समस्या जो मेरे पास अभी है, लेनदेन के रूप में कई कॉल करना है - मैं 2 कोड अपडेट करना और एक नया जोड़ना चाहता हूं।
आम तौर पर मैं अद्यतन कहूंगा, फिर सफलतापूर्वक हैंडलर कॉल दूसरे अपडेट में, और हैंडलर में दूसरे अपडेट में मैं जोड़ दूंगा जो नई आईडी वापस कर देगा।
कुछ की तरह:
-UPDATE CODE
|-UPDATE CODE
|-ADD CODE (only this one return something)
लेकिन मैं, लेन-देन के रूप में उन के सभी कॉल करने के लिए, इसलिए यदि कोड जोड़ टूट जाएगा अद्यतन रोलबैक होगा चाहते हैं।
प्रश्न:
यह एक सौदे के रूप में कई async प्रश्नों कॉल करने के लिए संभव है?
क्या मैं अपने उपरोक्त तरीकों को लेनदेन के रूप में कॉल कर सकता हूं या क्या मुझे अपनी प्रक्रियाओं को कॉल करने के लिए अलग विधि बनाना चाहिए? (मैं इसे एक से बचाना चाहता हूं क्योंकि यह सिर्फ एक ही कोड को एक विधि से दूसरे में कॉपी कर रहा है)
मैं यह जोड़ना चाहता हूं कि मैं .NET 3.5 का उपयोग करता हूं, इसलिए प्रतीक्षा करें और अन्य अच्छी सुविधाएं एक विकल्प नहीं हैं।
दुर्भाग्य से, एक लेनदेन में अपनी सभी प्रक्रियाओं को लपेटने के लिए आपको उन्हें एक दूसरे के बाद निष्पादित करना होगा। आप अन्यथा प्रति निष्पादन लेनदेन होने के अंत में समाप्त हो जाएगा। – LukeHennerley
ल्यूकहेनरली - क्या आप मुझे ऐसी विधि बनाने में मदद कर सकते हैं जो एकाधिक प्रक्रियाओं को एक के रूप में कॉल करेगी? आदर्श रूप से यह पैरामीटर के रूप में जोड़ने के लिए कोड और कोड को जोड़ने के लिए कोडों की सूची लेगा और निश्चित रूप से इसे – Misiu