问题描述
我有一个DB类,使所有数据库调用,例如如下:
I have a DB class that makes all DB calls like below:
public delegate void Part1_Callback(string message);
public delegate void Part2_Callback(DataTable dt);
public delegate void Part3_Callback(DataTable dt, int x, int y);
public delegate void ErrorHandler(string message);
public class CommandAndCallback<TCallback>
{
public SqlCommand Sql { get; set; }
public TCallback Callback { get; set; }
public ErrorHandler Error { get; set; }
}
class DB : SingletonBase<DB>
{
public static readonly string SqlConnectionString = @"Data Source=MyDB;Initial Catalog=Stats;Integrated Security=True;Asynchronous Processing=true;";
private DB()
{
}
public void Part2(Part2_Callback callback, ErrorHandler error)
{
SqlConnection conn = new SqlConnection(SqlConnectionString);
SqlCommand cmd = conn.CreateCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "Part2";
try
{
conn.Open();
}
catch (Exception ex)
{
error(ex.ToString());
return;
}
CommandAndCallback<Part2_Callback> ar = new CommandAndCallback<Part2_Callback>() { Callback = callback, Error = error, Sql = cmd };
IAsyncResult result = cmd.BeginExecuteReader(new AsyncCallback(Part2_Handler), ar, CommandBehavior.CloseConnection);
}
private void Part2_Handler(IAsyncResult result)
{
DataTable dt = new DataTable();
CommandAndCallback<Part2_Callback> ar = (CommandAndCallback<Part2_Callback>)result.AsyncState;
SqlDataReader dr;
if (result.IsCompleted)
{
dr = ar.Sql.EndExecuteReader(result);
}
else
dr = null;
dt.Load(dr);
dr.Close();
dt.Columns[3].ReadOnly = false;
ar.Callback(dt);
}
}
在我的主类我使用它,如下所示:
And in my main class I'm using it like so:
private void Form1_Enter(object sender, EventArgs e)
{
showStatus("Loading");
DB.Instance.Part2(Part2_OK, ErrorHandler);
}
private void ErrorHandler(string msg)
{
hideStatus();
viewStack1.InvokeIfRequired(c => { c.moveToFirst(); });
//MessageBox.Show(msg, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
private void Part2_OK(DataTable dt)
{
dataGridView1.InvokeIfRequired(c =>
{
c.DataSource = dt;
});
}
现在我有3种方法在我的DB类返回3个不同的数据集,为每一个类型的,我必须声明的委托。
如果将来我会添加更多的方法,那么我将不得不增加更多的代表。
Right now I have 3 methods in my DB class that return 3 different sets of data, for every type I must declare delegate.
If in future I'll add more methods then I'll have to add more delegates.
我可以删除代表的使用情况如何?我想简化我的类构建,这样它会很容易添加新的方法。
Can I remove usage of delegates? I would like to simplify build of my class so that it will be easy to add new methods.
我需要的是能够叫我DB类,像这样:
What I need is to be able to call my DB Class like so:
DB.Instance.PartX(PartX_OK, ErrorHandler);
PartX被声明为示
PartX is declared as shown
private void PartX_OK(DataTable dt, int x, int y, ...)
{
//logic here
}
能否动作&LT; T&GT;
被用来给,这样我就可以打电话给我处理程序使用多个参数?如果是的话怎么办?
Can Action<T>
be used to to that, so I can call my handlers with multiple parameters? If yes then how?
推荐答案
是的,我的意思是要回到你刚才的问题,所以你的函数会成为
Yes, I meant to get back to your earlier question, so your function would become
public void Part2(Action<DataTable> callback, ErrorHandler error)
{
SqlConnection conn = new SqlConnection(SqlConnectionString);
SqlCommand cmd = conn.CreateCommand();
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = "Part2";
try
{
conn.Open();
}
catch (Exception ex)
{
error(ex.ToString());
return;
}
CommandAndCallback<Action<DataTable>> ar = new CommandAndCallback<Action<DataTable>>() { Callback = callback, Error = error, Sql = cmd };
IAsyncResult result = cmd.BeginExecuteReader(new AsyncCallback(Part2_Handler), ar, CommandBehavior.CloseConnection);
}
private void Part2_Handler(IAsyncResult result)
{
DataTable dt = new DataTable();
CommandAndCallback<Action<DataTable>> ar = (CommandAndCallback<Action<DataTable>>)result.AsyncState;
SqlDataReader dr;
if (result.IsCompleted)
{
dr = ar.Sql.EndExecuteReader(result);
}
else
dr = null;
dt.Load(dr);
dr.Close();
dt.Columns[3].ReadOnly = false;
ar.Callback(dt);
}
这篇关于转换授人以行动&LT; T&GT; (动作&LT; T1,T2&GT;)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!