第二个BeginInvoke呼叫声明已经完成。为什么?

时间:2010-09-23 19:03:50

标签: c# .net multithreading begininvoke iasyncresult

我反复使用BeginInvoke调用方法。每次通话后,我都会调用EndInvoke。

问题是,对于第二次调用,返回的IAsyncResult中的IsCompleted成员在BeginInvoke调用后立即设置为true。

这会导致故障,因为程序会认为第二次通话已完成。

为什么会这样做,如何检测第二次通话何时真正完成?

Declarations:
IAsyncResult ar;
Mercury.J4000.Ui.frmMain.doPrintsDelegate printCallback;


The BeginInvoke call:
ar = printCallback.BeginInvoke (jobNameArray, copies, distances, null, null);


The EndInvoke call (in another method):
printCallback.EndInvoke(ar);

2 个答案:

答案 0 :(得分:2)

我的猜测是你在两个调用中使用相同的“ar”变量,因为你已经将它声明为一个字段。每个调用都应该有自己的实例;将该字段声明为List<IAsyncResult>,并编写必要的管道以初始化它,并将每个结果与每次调用相关联。您没有给我们足够的代码来帮助您完成该部分(实际上这个答案是猜测,因为您没有提供足够的代码。)

答案 1 :(得分:2)

我假设你正在做这样的事情:

IAsyncResult ar;
ar = printCallback.BeginInvoke(...);
// do some other stuff
ar = printCallback.BeginInvoke(...);

如果在第二次异步操作开始之前没有完成第一次异步操作,那么您将失去IAsyncResult值。第二次电话会覆盖它。

不知何故,您必须跟踪单个IAsyncResult引用并将它们与您所做的调用相关联。如果您只有一个或两个,则可以轻松跟踪单个变量或集合(通常为List或数组)。

这个问题可能有助于您:Can I use a single instance of a delegate to start multiple Asynchronous Requests?

我还建议您考虑为异步委托使用回调。这样,正确的IAsyncResult作为参数传递给回调,并且没有模糊性的可能性。但是,使用AsyncCallback可能需要对代码进行重大修改。