我创建了一个我打算调用Async的委托。
Delegate Sub GetPartListDataFromServer(ByVal dvOriginal As DataView, ByVal ProgramID As Integer)
Dim dlgGetPartList As GetPartListDataFromServer
Dim dlgGetPartList As New GetPartListDataFromServer(AddressOf AsyncThreadMethod_GetPartListDataFromServer)
dlgGetPartList.BeginInvoke(ucboPart.DataSource, ucboProgram.Value, AddressOf AsyncCallback_GetPartListDataFromServer, Nothing)
该方法运行并完成所需的操作
Sub AsyncCallback_GetPartListDataFromServer(ByVal ar As IAsyncResult)
dlgGetPartList.EndInvoke(Nothing)
End Sub
只要在没有正在运行的BeginInvoke / Thread操作的情况下,只在代理上启动BeginInvoke的方法运行,它就会起作用。问题是,当委托中的另一个线程仍在运行且尚未进行EndInvoke时,可以调用新线程。
如果需要,程序需要能够让委托一次在多个实例中运行,并且它们都需要完成并调用EndInvoke。一旦我启动另一个BeginInvoke,我将丢失对第一个BeginInvoke的引用,因此我无法使用EndInvoke清理新线程。
什么是解决此问题的清洁解决方案和最佳做法?
答案 0 :(得分:2)
您只需要保留对代表的一个引用;每次调用时都不需要创建新的。
不是将Nothing
传递给EndInvoke
,而是传递ar
。这将为您提供特定调用的结果。
Sub AsyncCallback_GetPartListDataFromServer(ByVal ar As IAsyncResult)
dlgGetPartList.EndInvoke(ar)
End Sub
如果您希望能够取消特定的调用,那么您将希望保留BeginInvoke
的结果(这是IAsyncResult
的相同实例,该结果将传递给您你上面的回调)。
答案 1 :(得分:1)
调用BeginInvoke时,需要将对象作为状态参数传递。
class Program
{
delegate void SampleDelegate(string message);
static void SampleDelegateMethod(string message)
{
Console.WriteLine(message);
}
static void Callback(object obj)
{
IAsyncResult result = obj as IAsyncResult;
SampleDelegate del = result.AsyncState as SampleDelegate;
del.EndInvoke(result);
Console.WriteLine("Finished calling EndInvoke");
}
static void Main()
{
for (int i = 0; i < 10; i++)
{
// Instantiate delegate with named method:
SampleDelegate d1 = SampleDelegateMethod;
//d1 is passed as a state
d1.BeginInvoke("Hello", Callback, d1);
}
Console.WriteLine("Press any key to continue");
Console.ReadLine();
}
}