public delegate DataTable QueryDelegate(string table,string express);private void Query() { string express =" where 1=1"; QueryDelegate querydelegate=new QueryDelegate(dbmanager.ReadTable) querydelegate.BeginInvoke("table",express,new AsyncCallback(QueryCompeled),querydelegate); } private void QueryCompeled(IAsyncResult ar) { try{ QueryDelegate querydelegate=(QueryDelegate)ar.AsyncState; DataTable dt=querydelegate.EndInvoke(ar); dataGrid.DataSource=dt; } catch(Exception e) { Console.Write(e);//这种做法会报错,提示+ ex {"Controls created on one thread cannot be parented to a control on a different thread." } System.Exception} }以上代码出自: http://neozhu.cnblogs.com/archive/2006/04/07/369144.html
《.NET本质论》上写得很清楚,建议看看这本书下面这段代码,是个小实例,说明异步Delegate是如何使用的: 设计了两个代理,一个是有返回值的,一个是没有返回值的。 private void button1_Click(object sender, System.EventArgs e) { MessageBox.Show("GetDate process is begin."); GetDateDelegate gd = new GetDateDelegate(this.GetCurrentDate); gd.BeginInvoke(new AsyncCallback(this.CallbackMethod),null); } // Invoke a complex process. private void button2_Click(object sender, System.EventArgs e) { MessageBox.Show("Complex process is begin."); ComplexProcessDelegate cpd = new ComplexProcessDelegate(this.DoComplexWork);
// cpd(); // synchornized invoke. IAsyncResult iar = cpd.BeginInvoke(null, null); // aynchornized invoke. // iar.AsyncWaitHandle.WaitOne(); // waiting util the process is over. // Synchornized ... MessageBox.Show("Complex process is end."); } private void DoComplexWork() { System.Threading.Thread.Sleep(5000); } private string GetCurrentDate() { System.Threading.Thread.Sleep(5000); return DateTime.Now.ToString(); } private void CallbackMethod(IAsyncResult iar) { AsyncResult ar = (AsyncResult) iar; GetDateDelegate gd = (GetDateDelegate) ar.AsyncDelegate; string msg = gd.EndInvoke(iar); MessageBox.Show(msg); } public delegate void ComplexProcessDelegate(); public delegate string GetDateDelegate();
.NET Framework 允许您异步调用任何方法。定义与您需要调用的方法具有相同签名的委托;公共语言运行库将自动为该委托定义具有适当签名的 BeginInvoke 和 EndInvoke 方法。BeginInvoke 方法用于启动异步调用。它与您需要异步执行的方法具有相同的参数,只不过还有两个额外的参数(将在稍后描述)。BeginInvoke 立即返回,不等待异步调用完成。BeginInvoke 返回 IasyncResult,可用于监视调用进度。EndInvoke 方法用于检索异步调用结果。调用 BeginInvoke 后可随时调用 EndInvoke 方法;如果异步调用未完成,EndInvoke 将一直阻塞到异步调用完成。EndInvoke 的参数包括您需要异步执行的方法的 out 和 ref 参数(在 Visual Basic 中为 <Out> ByRef 和 ByRef)以及由 BeginInvoke 返回的 IAsyncResult。注意 Visual Studio .NET 中的智能感知功能会显示 BeginInvoke 和 EndInvoke 的参数。如果您没有使用 Visual Studio 或类似的工具,或者您使用的是 C# 和 Visual Studio .NET,请参见异步方法签名获取有关运行库为这些方法定义的参数的描述。 本主题中的代码演示了四种使用 BeginInvoke 和 EndInvoke 进行异步调用的常用方法。调用了 BeginInvoke 后,可以: 进行某些操作,然后调用 EndInvoke 一直阻塞到调用完成。 使用 IAsyncResult.AsyncWaitHandle 获取 WaitHandle,使用它的 WaitOne 方法将执行一直阻塞到发出 WaitHandle 信号,然后调用 EndInvoke。 轮询由 BeginInvoke 返回的 IAsyncResult,确定异步调用何时完成,然后调用 EndInvoke。 将用于回调方法的委托传递给 BeginInvoke。该方法在异步调用完成后在 ThreadPool 线程上执行,它可以调用 EndInvoke。 警告 始终在异步调用完成后调用 EndInvoke。 测试方法和异步委托 四个示例全部使用同一个长期运行的测试方法 TestMethod。该方法显示一个表明它已开始处理的控制台信息,休眠几秒钟,然后结束。TestMethod 有一个 out 参数(在 Visual Basic 中为 <Out> ByRef),它演示了如何将这些参数添加到 BeginInvoke 和 EndInvoke 的签名中。您可以用类似的方式处理 ref 参数(在 Visual Basic 中为 ByRef)。下面的代码示例显示 TestMethod 以及代表 TestMethod 的委托;若要使用任一示例,请将示例代码追加到这段代码中。注意 为了简化这些示例,TestMethod 在独立于 Main() 的类中声明。或者,TestMethod 可以是包含 Main() 的同一类中的 static 方法(在 Visual Basic 中为 Shared)。[C#] using System; using System.Threading; public class AsyncDemo { // The method to be executed asynchronously. // public string TestMethod(int callDuration, out int threadId) { Console.WriteLine("Test method begins."); Thread.Sleep(callDuration); threadId = AppDomain.GetCurrentThreadId(); return "MyCallTime was " + callDuration.ToString(); } }// The delegate must have the same signature as the method // you want to call asynchronously. public delegate string AsyncDelegate(int callDuration, out int threadId);使用 EndInvoke 等待异步调用 异步执行方法的最简单方式是以 BeginInvoke 开始,对主线程执行一些操作,然后调用 EndInvoke。EndInvoke 直到异步调用完成后才返回。这种技术非常适合文件或网络操作,但是由于它阻塞 EndInvoke,所以不要从用户界面的服务线程中使用它。[C#] public class AsyncMain { static void Main(string[] args) { // The asynchronous method puts the thread id here. int threadId; // Create an instance of the test class. AsyncDemo ad = new AsyncDemo(); // Create the delegate. AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);
// Initiate the asychronous call. IAsyncResult ar = dlgt.BeginInvoke(3000, out threadId, null, null); Thread.Sleep(0); Console.WriteLine("Main thread {0} does some work.", AppDomain.GetCurrentThreadId()); // Wait for the WaitHandle to become signaled. ar.AsyncWaitHandle.WaitOne(); // Perform additional processing here. // Call EndInvoke to retrieve the results. string ret = dlgt.EndInvoke(out threadId, ar); Console.WriteLine("The call executed on thread {0}, with return value \"{1}\".", threadId, ret); } }轮询异步调用完成 您可以使用由 BeginInvoke 返回的 IAsyncResult 的 IsCompleted 属性来发现异步调用何时完成。从用户界面的服务线程中进行异步调用时可以执行此操作。轮询完成允许用户界面线程继续处理用户输入。 [C#] public class AsyncMain { static void Main(string[] args) { // The asynchronous method puts the thread id here. int threadId; // Create an instance of the test class. AsyncDemo ad = new AsyncDemo(); // Create the delegate. AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);
// Initiate the asychronous call. IAsyncResult ar = dlgt.BeginInvoke(3000, out threadId, null, null); // Poll while simulating work. while(ar.IsCompleted == false) { Thread.Sleep(10); } // Call EndInvoke to retrieve the results. string ret = dlgt.EndInvoke(out threadId, ar); Console.WriteLine("The call executed on thread {0}, with return value \"{1}\".", threadId, ret); } }异步调用完成时执行回调方法 如果启动异步调用的线程不需要处理调用结果,则可以在调用完成时执行回调方法。回调方法在 ThreadPool 线程上执行。要使用回调方法,必须将代表该方法的 AsyncCallback 委托传递给 BeginInvoke。也可以传递包含回调方法将要使用的信息的对象。例如,可以传递启动调用时曾使用的委托,以便回调方法能够调用 EndInvoke。[C#] public class AsyncMain { // Asynchronous method puts the thread id here. private static int threadId; static void Main(string[] args) { // Create an instance of the test class. AsyncDemo ad = new AsyncDemo(); // Create the delegate. AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);
// Initiate the asychronous call. Include an AsyncCallback // delegate representing the callback method, and the data // needed to call EndInvoke. IAsyncResult ar = dlgt.BeginInvoke(3000, out threadId, new AsyncCallback(CallbackMethod), dlgt ); Console.WriteLine("Press Enter to close application."); Console.ReadLine(); }
// Callback method must have the same signature as the // AsyncCallback delegate. static void CallbackMethod(IAsyncResult ar) { // Retrieve the delegate. AsyncDelegate dlgt = (AsyncDelegate) ar.AsyncState; // Call EndInvoke to retrieve the results. string ret = dlgt.EndInvoke(out threadId, ar); Console.WriteLine("The call executed on thread {0}, with return value \"{1}\".", threadId, ret); } }
Invoking methods asynchronously using delegates.BeginInvoke(parameter list, AsyncCallback callback, object state); EndInvoke(IAsyncResult result);When BeginInvoke finishes, .net calls the supplied callback function inside which you are supposed to call the EndInvoke method. AsyncCallback: delegate that points to the callback function that will be called when the method completes. object state: You can pass some state information to the method via state parameter. This is usualful in case you want to pass some information other than method parameter.public void MyCallback(IAsyncResult result);
给你写个: public void Write1() { Thread.Sleep(4000); MessageBox.Show("方法1"); } public void Write2() { System.Threading.Thread.Sleep(4000); MessageBox.Show("方法2"); } private void button1_Click(object sender, EventArgs e) { this.textBox3.Text = "test"; Form1 MyForm1 = new Form1(); MyMethodDelegate d1 = new MyMethodDelegate(MyForm1.Write1); MyMethodDelegate d2 = new MyMethodDelegate(MyForm1.Write2); AsyncResult MyResult1, MyResult2; MyResult1 = (AsyncResult)d1.BeginInvoke(null, null); MyResult2 = (AsyncResult)d2.BeginInvoke(null,null); WaitHandle[] waitHandle = new WaitHandle[2] { MyResult1.AsyncWaitHandle,MyResult2.AsyncWaitHandle}; MyResult1.AsyncWaitHandle.WaitOne(); MyResult2.AsyncWaitHandle.WaitOne(); }
ms-help://MS.MSDNQTR.2003APR.1033/cpref/html/frlrfsystemiasyncresultclasstopic.htm
{
string express =" where 1=1";
QueryDelegate querydelegate=new QueryDelegate(dbmanager.ReadTable)
querydelegate.BeginInvoke("table",express,new AsyncCallback(QueryCompeled),querydelegate);
}
private void QueryCompeled(IAsyncResult ar)
{
try{
QueryDelegate querydelegate=(QueryDelegate)ar.AsyncState;
DataTable dt=querydelegate.EndInvoke(ar);
dataGrid.DataSource=dt;
}
catch(Exception e)
{
Console.Write(e);//这种做法会报错,提示+ ex {"Controls created on one thread cannot be parented to a control on a different thread." } System.Exception}
}以上代码出自:
http://neozhu.cnblogs.com/archive/2006/04/07/369144.html
设计了两个代理,一个是有返回值的,一个是没有返回值的。 private void button1_Click(object sender, System.EventArgs e)
{
MessageBox.Show("GetDate process is begin.");
GetDateDelegate gd = new GetDateDelegate(this.GetCurrentDate);
gd.BeginInvoke(new AsyncCallback(this.CallbackMethod),null);
} // Invoke a complex process.
private void button2_Click(object sender, System.EventArgs e)
{
MessageBox.Show("Complex process is begin.");
ComplexProcessDelegate cpd =
new ComplexProcessDelegate(this.DoComplexWork);
// cpd(); // synchornized invoke.
IAsyncResult iar = cpd.BeginInvoke(null, null); // aynchornized invoke.
// iar.AsyncWaitHandle.WaitOne(); // waiting util the process is over.
// Synchornized ...
MessageBox.Show("Complex process is end.");
} private void DoComplexWork()
{
System.Threading.Thread.Sleep(5000);
} private string GetCurrentDate()
{
System.Threading.Thread.Sleep(5000);
return DateTime.Now.ToString();
} private void CallbackMethod(IAsyncResult iar)
{
AsyncResult ar = (AsyncResult) iar;
GetDateDelegate gd = (GetDateDelegate) ar.AsyncDelegate;
string msg = gd.EndInvoke(iar);
MessageBox.Show(msg);
} public delegate void ComplexProcessDelegate();
public delegate string GetDateDelegate();
本主题中的代码演示了四种使用 BeginInvoke 和 EndInvoke 进行异步调用的常用方法。调用了 BeginInvoke 后,可以: 进行某些操作,然后调用 EndInvoke 一直阻塞到调用完成。
使用 IAsyncResult.AsyncWaitHandle 获取 WaitHandle,使用它的 WaitOne 方法将执行一直阻塞到发出 WaitHandle 信号,然后调用 EndInvoke。
轮询由 BeginInvoke 返回的 IAsyncResult,确定异步调用何时完成,然后调用 EndInvoke。
将用于回调方法的委托传递给 BeginInvoke。该方法在异步调用完成后在 ThreadPool 线程上执行,它可以调用 EndInvoke。
警告 始终在异步调用完成后调用 EndInvoke。
测试方法和异步委托
四个示例全部使用同一个长期运行的测试方法 TestMethod。该方法显示一个表明它已开始处理的控制台信息,休眠几秒钟,然后结束。TestMethod 有一个 out 参数(在 Visual Basic 中为 <Out> ByRef),它演示了如何将这些参数添加到 BeginInvoke 和 EndInvoke 的签名中。您可以用类似的方式处理 ref 参数(在 Visual Basic 中为 ByRef)。下面的代码示例显示 TestMethod 以及代表 TestMethod 的委托;若要使用任一示例,请将示例代码追加到这段代码中。注意 为了简化这些示例,TestMethod 在独立于 Main() 的类中声明。或者,TestMethod 可以是包含 Main() 的同一类中的 static 方法(在 Visual Basic 中为 Shared)。[C#]
using System;
using System.Threading; public class AsyncDemo {
// The method to be executed asynchronously.
//
public string TestMethod(int callDuration, out int threadId) {
Console.WriteLine("Test method begins.");
Thread.Sleep(callDuration);
threadId = AppDomain.GetCurrentThreadId();
return "MyCallTime was " + callDuration.ToString();
}
}// The delegate must have the same signature as the method
// you want to call asynchronously.
public delegate string AsyncDelegate(int callDuration, out int threadId);使用 EndInvoke 等待异步调用
异步执行方法的最简单方式是以 BeginInvoke 开始,对主线程执行一些操作,然后调用 EndInvoke。EndInvoke 直到异步调用完成后才返回。这种技术非常适合文件或网络操作,但是由于它阻塞 EndInvoke,所以不要从用户界面的服务线程中使用它。[C#]
public class AsyncMain {
static void Main(string[] args) {
// The asynchronous method puts the thread id here.
int threadId; // Create an instance of the test class.
AsyncDemo ad = new AsyncDemo(); // Create the delegate.
AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);
// Initiate the asychronous call.
IAsyncResult ar = dlgt.BeginInvoke(3000,
out threadId, null, null); Thread.Sleep(0);
Console.WriteLine("Main thread {0} does some work.",
AppDomain.GetCurrentThreadId()); // Wait for the WaitHandle to become signaled.
ar.AsyncWaitHandle.WaitOne(); // Perform additional processing here.
// Call EndInvoke to retrieve the results.
string ret = dlgt.EndInvoke(out threadId, ar); Console.WriteLine("The call executed on thread {0}, with return value \"{1}\".", threadId, ret);
}
}轮询异步调用完成
您可以使用由 BeginInvoke 返回的 IAsyncResult 的 IsCompleted 属性来发现异步调用何时完成。从用户界面的服务线程中进行异步调用时可以执行此操作。轮询完成允许用户界面线程继续处理用户输入。
[C#]
public class AsyncMain {
static void Main(string[] args) {
// The asynchronous method puts the thread id here.
int threadId; // Create an instance of the test class.
AsyncDemo ad = new AsyncDemo(); // Create the delegate.
AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);
// Initiate the asychronous call.
IAsyncResult ar = dlgt.BeginInvoke(3000,
out threadId, null, null); // Poll while simulating work.
while(ar.IsCompleted == false) {
Thread.Sleep(10);
} // Call EndInvoke to retrieve the results.
string ret = dlgt.EndInvoke(out threadId, ar); Console.WriteLine("The call executed on thread {0}, with return value \"{1}\".", threadId, ret);
}
}异步调用完成时执行回调方法
如果启动异步调用的线程不需要处理调用结果,则可以在调用完成时执行回调方法。回调方法在 ThreadPool 线程上执行。要使用回调方法,必须将代表该方法的 AsyncCallback 委托传递给 BeginInvoke。也可以传递包含回调方法将要使用的信息的对象。例如,可以传递启动调用时曾使用的委托,以便回调方法能够调用 EndInvoke。[C#]
public class AsyncMain {
// Asynchronous method puts the thread id here.
private static int threadId; static void Main(string[] args) {
// Create an instance of the test class.
AsyncDemo ad = new AsyncDemo(); // Create the delegate.
AsyncDelegate dlgt = new AsyncDelegate(ad.TestMethod);
// Initiate the asychronous call. Include an AsyncCallback
// delegate representing the callback method, and the data
// needed to call EndInvoke.
IAsyncResult ar = dlgt.BeginInvoke(3000,
out threadId,
new AsyncCallback(CallbackMethod),
dlgt ); Console.WriteLine("Press Enter to close application.");
Console.ReadLine();
}
// Callback method must have the same signature as the
// AsyncCallback delegate.
static void CallbackMethod(IAsyncResult ar) {
// Retrieve the delegate.
AsyncDelegate dlgt = (AsyncDelegate) ar.AsyncState; // Call EndInvoke to retrieve the results.
string ret = dlgt.EndInvoke(out threadId, ar); Console.WriteLine("The call executed on thread {0}, with return value \"{1}\".", threadId, ret);
}
}
EndInvoke(IAsyncResult result);When BeginInvoke finishes, .net calls the supplied callback function inside which you are supposed to call the EndInvoke method.
AsyncCallback: delegate that points to the callback function that will be called when the method completes.
object state: You can pass some state information to the method via state parameter. This is usualful in case you want to pass some information other than method parameter.public void MyCallback(IAsyncResult result);
public void Write1()
{
Thread.Sleep(4000);
MessageBox.Show("方法1");
} public void Write2()
{
System.Threading.Thread.Sleep(4000);
MessageBox.Show("方法2");
} private void button1_Click(object sender, EventArgs e)
{
this.textBox3.Text = "test";
Form1 MyForm1 = new Form1();
MyMethodDelegate d1 = new MyMethodDelegate(MyForm1.Write1);
MyMethodDelegate d2 = new MyMethodDelegate(MyForm1.Write2); AsyncResult MyResult1, MyResult2;
MyResult1 = (AsyncResult)d1.BeginInvoke(null, null);
MyResult2 = (AsyncResult)d2.BeginInvoke(null,null); WaitHandle[] waitHandle = new WaitHandle[2] { MyResult1.AsyncWaitHandle,MyResult2.AsyncWaitHandle};
MyResult1.AsyncWaitHandle.WaitOne();
MyResult2.AsyncWaitHandle.WaitOne(); }