如何在asp.net中等待所有AsyncCallback返回
本文关键字:AsyncCallback 返回 等待 asp net | 更新日期: 2023-09-27 18:09:38
我使用多线程数据库查询一次检索多个数据表。我使用了一个被锁定的列表…一旦所有的回调函数都被返回,我想要返回列表。我想知道如何等待所有的回调完成。
private Object TableLock = new Object();
private List<DataTable> tables_from_callback = new List<DataTable>();
private void ExecReaderHandleCallback(IAsyncResult result)
{
SqlCommand command = (SqlCommand)result.AsyncState;
SqlDataReader reader = command.EndExecuteReader(result);
DataTable dt = new DataTable();
dt.Load(reader);
lock (TableLock)
{
tables_from_callback.Add(dt);
}
}
public List<DataTable> BegExecReader(String query, int query)
{
conn = new SqlConnection(connectionString);
try
{
conn.Open();
WaitHandle[] waitHandles = new WaitHandle[query];
IAsyncResult[] results = new IAsyncResult[query];
SqlCommand[] cmds = new SqlCommand[query];
for (int i = 0; i < query; i++ )
{
SqlCommand cmd = new SqlCommand();
cmd.Connection = conn;
cmd.CommandText = query;
cmd.CommandType = CommandType.Text;
cmd.CommandTimeout = queryTIMEOUT;
AsyncCallback callback = new AsyncCallback(ExecReaderHandleCallback);
cmd.BeginExecuteReader(callback, cmd);
cmds[i] = cmd;
}
/* ????
here I need to wait for the callbacks to finish
HOW?
??????? */
return tables_from_callback;
}
finally
{
conn.Close();
}
}
我做过类似的事情,但没有使用
的回调IAsyncResult result = cmd.BeginExecuteReader();
results[i] = result;
waitHandles[i] = result.AsyncWaitHandle;
...
WaitHandle.WaitAll(waitHandles);
但是现在我必须使用回调,所以我没有等待句柄。
一种比较俗气的方法是使用两个上下文都可以访问的变量。通过上下文,我指的是传递回调的调用者和回调本身。
static void Main(string[] args)
{
int x = 1;
Task.Run(() =>
{
Thread.Sleep(5000);
Console.WriteLine("Yay!");
x = 0;
});
while (x != 0) { Thread.Yield(); }
Console.WriteLine("Done");
Console.ReadKey(true);
}
我正在使用任务。运行来模拟你的回调情况;然而,这个原则仍然适用于回调的情况…不同之处在于,您将使用类级变量或(类似于)静态变量。你也可以使用类似信号量的东西,只要这个信号量不是马上发出信号……这样的。
static void Main(string[] args)
{
Semaphore s = new Semaphore(1, 2);
Task.Run(() =>
{
s.WaitOne();
Thread.Sleep(5000);
Console.WriteLine("Yay!");
s.Release();
});
Thread.Sleep(100);
s.WaitOne();
Console.WriteLine("Done");
Console.ReadKey(true);
}