2010-09-23 106 views
0

我反复调用BeginInvoke的方法。每次通话后,我都会调用EndInvoke。第二次BeginInvoke呼叫声明已完成。为什么?

问题是,对于第二个调用,在BeginInvoke调用之后,返回的IAsyncResult中的IsCompleted成员被设置为true IMMEDIATELY。

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

为什么会这样做,以及如何检测第二次调用何时完成?

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); 
+0

你介意分享你的代码吗? – 2010-09-23 19:05:10

+0

请显示验证码。不要让我们猜测你做错了什么。 – 2010-09-23 19:05:11

+0

使用代码更新您的问题,而不是将其作为评论发布。 – 2010-09-23 19:13:28

回答

2

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

+0

是的,我使用的是相同的变量,因为Microsoft文档对此进行了关于EndInvoke参数的说明:“表示调用BeginInvoke时返回的特定调用异步操作的IAsyncResult。” – alankdkd 2010-09-23 19:38:51

+0

@alankdkd“表示特定的调用异步操作”表示每次调用BeginInvoke时都需要一个新变量来跟踪结果。 – 2010-09-23 19:48:29

+0

@alankdkd - 然后请将我的回答标记为答案(因为jim在我回答10分钟后回答相同) – x0n 2010-09-23 20:07:36

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可能需要对代码进行重大的重构。