等待异步委托调用完成的最佳方法 [英] best way to wait for async delegate calls to complete

查看:82
本文介绍了等待异步委托调用完成的最佳方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



为了清楚起见,我省略了大部分代码,但下面的循环是如何使用异步调用委托函数的方式。在我开始每次调用之后

我正在递增一个计数器,然后让主线程休眠,直到

计数器回到零。每个呼叫的回叫功能递减计数器。除了使用计数器之外,有没有更好的方法让线程等待所有调用

完成?我已经看到了一些使用

IAsyncResult的事情,但我不知道如何在我的情况下这样做,因为我正在制作1

到n打电话。

谢谢,

瑞恩


对于iProviderIndex因为Int32 = 0到oProviders.Length - 1

oLookupReq = New Schema.LookupRequest

oLookup =

CType(Activator.CreateInstance(Type.GetType(oLooku pType.class_id)),

Schema.IPrequalLookup)

Del = New LookupAsyncDelegate(AddressOf oLookup.GetPrequalResponse)

Del.BeginInvoke(oLookupReq,AddressOf LookupCallback,Del)

IncrementAsyncOps()

下一个iProviderIndex


虽然m_async_ops> 0

Thread.Sleep(200)

结束时

Hi,
I''ve omitted a large chunk of the code for clarity but the loop below is how
I''m calling a delegate function asynchronously. After I start the each call
I''m incrementing a counter and then making the main thread sleep until the
counter gets back to zero. The call back function for each call decrements
the counter. Is there a better way to make the thread wait until all calls
are complete besides using the counter? I''ve seen some things with using an
IAsyncResult but I''m not sure how to do that in my case since I''m making 1
to n calls.
Thanks,
Ryan

For iProviderIndex As Int32 = 0 To oProviders.Length - 1
oLookupReq = New Schema.LookupRequest
oLookup =
CType(Activator.CreateInstance(Type.GetType(oLooku pType.class_id)),
Schema.IPrequalLookup)
Del = New LookupAsyncDelegate(AddressOf oLookup.GetPrequalResponse)
Del.BeginInvoke(oLookupReq, AddressOf LookupCallback, Del)
IncrementAsyncOps()
Next iProviderIndex

While m_async_ops > 0
Thread.Sleep(200)
End While

推荐答案

总是有其他方法,你的解决方案有很大的优势

简单

另一个方法可能是在课堂上写你的待办事项代码,启动这些就好了

另一个线程并使用队列类跟踪它们


如果我认为更多我知道我可以找到其他结构

获得已完成的工作,但是你的方法并不是那么糟糕

并且在我看来它有很大的优势,很清楚它的作用是什么


IAsyncResult将从该方法返回一个值,我不知道

如何在这种情况下有所帮助


问候

Michel Posseth [MCP]


" ryan" < RO ************* @ inval.hotmail.com> schreef in bericht

新闻:eI ************** @ TK2MSFTNGP09.phx.gbl ...
well there are always other aproaches , your solution has the big advantage
of simplicity
another aproach could be to write your todo code in a class , start these on
another thread and keep track of them with a queue class

if i think a litle more i know for sure that i can find other constructions
to get the job done , however your aproach isn`t so bad at all
and has the big advantage in my opinion that it is clear in what it does

IAsyncResult will give you a value back from the method , i do not see how
this could help in this situation

regards

Michel Posseth [MCP]


"ryan" <ro*************@inval.hotmail.com> schreef in bericht
news:eI**************@TK2MSFTNGP09.phx.gbl...
为了清楚起见,我省略了大量的代码,但下面的循环是如何异步调用委托函数。在我开始每个
电话后,我正在递增一个计数器,然后使主线程保持睡眠状态,直到计数器恢复为零。每次调用的回调函数
递减计数器。除了使用计数器之外,还有更好的方法让线程等待所有呼叫完成吗?我已经看过使用IAsyncResult的一些事情,但我不知道如何在我的
情况下这样做,因为我正在拨打1到n个电话。
谢谢,
Ryan

对于iProviderIndex As Int32 = 0 to oProviders.Length - 1
oLookupReq = New Schema.LookupRequest
oLookup =
CType(Activator.CreateInstance (Type.GetType(oLooku pType.class_id)),
Schema.IPrequalLookup)
Del = New LookupAsyncDelegate(AddressOf oLookup.GetPrequalResponse)
Del.BeginInvoke(oLookupReq,AddressOf LookupCallback,Del)
IncrementAsyncOps()
下一个iProviderIndex

而m_async_ops> 0
Thread.Sleep(200)
结束时
Hi,
I''ve omitted a large chunk of the code for clarity but the loop below is
how I''m calling a delegate function asynchronously. After I start the each
call I''m incrementing a counter and then making the main thread sleep
until the counter gets back to zero. The call back function for each call
decrements the counter. Is there a better way to make the thread wait
until all calls are complete besides using the counter? I''ve seen some
things with using an IAsyncResult but I''m not sure how to do that in my
case since I''m making 1 to n calls.
Thanks,
Ryan

For iProviderIndex As Int32 = 0 To oProviders.Length - 1
oLookupReq = New Schema.LookupRequest
oLookup =
CType(Activator.CreateInstance(Type.GetType(oLooku pType.class_id)),
Schema.IPrequalLookup)
Del = New LookupAsyncDelegate(AddressOf oLookup.GetPrequalResponse)
Del.BeginInvoke(oLookupReq, AddressOf LookupCallback, Del)
IncrementAsyncOps()
Next iProviderIndex

While m_async_ops > 0
Thread.Sleep(200)
End While



Ryan,


您可以使用ManualResetEvent类。在循环之前创建一个ManualResetEvent

。当m_async_ops计数器下降到0时,让LookupCallback方法通过

来调用事件。

循环之后通过调用WaitOne方法等待事件。我建议将m_async_ops计数器的初始值设置为你要在循环之前调用的代理数量



否则,如果您不小心,可能会得到奇怪的结果。


此外,您发布的代码不是线程安全的。 while循环

检查m_async_ops是否为> 0可能永远不会结束。原因是

,因为该线程可能没有看到其他线程的变化是
制作。你需要有一些同步机制来

至少做一个m_async_ops的易失性读取。


Brian


ryan写道:
Ryan,

You could use the ManualResetEvent class. Create a ManualResetEvent
before the loop. Have the LookupCallback method signal the event by
calling the Set method when the m_async_ops counter gets down to 0.
After the loop wait for the event by calling the WaitOne method. I
recommend setting the m_async_ops counter''s initial value to the number
of delegates your are going to invoke before the loop though.
Otherwise, you may get strange results if you''re not careful.

Also, the code you''ve posted is not thread-safe. The while loop
checking to see if m_async_ops is > 0 may never end. The reason is
because that thread may not be seeing the changes other threads are
making. You need to have some synchronization mechanism in place to at
least do a volatile read of m_async_ops.

Brian

ryan wrote:

为了清楚起见,我省略了很大一部分代码,但下面的循环是如何
我正在调用委托函数异步。在我开始每次调用之后
我正在递增一个计数器,然后让主线程休眠,直到
计数器回到零。每次调用的回调函数递减计数器。除了使用计数器之外,有没有更好的方法让线程等到所有调用完成
之后?我已经看过一些使用了
IAsyncResult的东西,但是我不知道如何在我的情况下这样做,因为我正在为n个电话做一次。
谢谢,
Ryan

对于iProviderIndex As Int32 = 0 to oProviders.Length - 1
oLookupReq = New Schema.LookupRequest
oLookup =
CType(Activator.CreateInstance (Type.GetType(oLooku pType.class_id)),
Schema.IPrequalLookup)
Del = New LookupAsyncDelegate(AddressOf oLookup.GetPrequalResponse)
Del.BeginInvoke(oLookupReq,AddressOf LookupCallback,Del)
IncrementAsyncOps()
下一个iProviderIndex

而m_async_ops> 0
Thread.Sleep(200)
结束时
Hi,
I''ve omitted a large chunk of the code for clarity but the loop below is how
I''m calling a delegate function asynchronously. After I start the each call
I''m incrementing a counter and then making the main thread sleep until the
counter gets back to zero. The call back function for each call decrements
the counter. Is there a better way to make the thread wait until all calls
are complete besides using the counter? I''ve seen some things with using an
IAsyncResult but I''m not sure how to do that in my case since I''m making 1
to n calls.
Thanks,
Ryan

For iProviderIndex As Int32 = 0 To oProviders.Length - 1
oLookupReq = New Schema.LookupRequest
oLookup =
CType(Activator.CreateInstance(Type.GetType(oLooku pType.class_id)),
Schema.IPrequalLookup)
Del = New LookupAsyncDelegate(AddressOf oLookup.GetPrequalResponse)
Del.BeginInvoke(oLookupReq, AddressOf LookupCallback, Del)
IncrementAsyncOps()
Next iProviderIndex

While m_async_ops > 0
Thread.Sleep(200)
End While






Ryan,

除了其他评论:


我会将从BeginInvoke返回的IAsyncResult值存储在一个列表中,

然后我做了一个For Each over a doing依次对每一个进行EndInvoke。


类似于:


Public Delegate Sub DoSomething()


Public Shared Sub Something()

System.Threading.Thread.Sleep(TimeSpan.FromSeconds(0.5))

End Sub


Public Shared Sub Main()

Dim方法As DoSomething = AddressOf Something

Dim results As New ArrayList


For index As Integer = 1 To 100

Dim results As IAsyncResult = method.BeginInvoke(Nothing,

Nothing)

results.Add(result)

下一页


每个结果作为IAsyncResult结果

尝试

method.EndInvoke(结果)

Catch ex As Exception

''报告错误但继续......

Debug.WriteLine(ex,End Invoke)

结束尝试

下一页


结束子


这允许主线程静静等待直到所有工人们已经完成了b $ b。因为工人正在异步完成EndInvoke

要么对于已完成的工人要么快速返回,要么等待忙碌的

工人...


注意根据调用的方法,您可能希望将Delegate

本身(方法变量)也存储在列表中,或者作为AsyncState存储在

BeginInvoke调用中...


-

Jay [MVP - Outlook]

..NET应用程序架构师,爱好者,&福音传教士

T.S.布拉德利 - http://www.tsbradley.net

" ;莱恩" < RO ************* @ inval.hotmail.com>在留言中写道

新闻:eI ************** @ TK2MSFTNGP09.phx.gbl ...

|

|为了清晰起见,我省略了大部分代码,但下面的循环是

怎么样

|我异步调用委托函数。在我开始每个

之后打电话

|我正在递增一个计数器,然后让主线程一直睡到

|计数器回到零。每次调用的回调函数递减

|柜台。是否有更好的方法让线程等到所有调用

|除了使用柜台外还完整吗?我见过一些使用



|的东西IAsyncResult但我不确定如何在我的情况下这样做,因为我正在制作1

|到n个电话。

|谢谢,

| Ryan

|

|对于iProviderIndex As Int32 = 0 to oProviders.Length - 1

| oLookupReq = New Schema.LookupRequest

| oLookup =

| CType(Activator.CreateInstance(Type.GetType(oLooku pType.class_id)),

| Schema.IPrequalLookup)

| Del = New LookupAsyncDelegate(AddressOf oLookup.GetPrequalResponse)

| Del.BeginInvoke(oLookupReq,AddressOf LookupCallback,Del)

| IncrementAsyncOps()

|下一个iProviderIndex

|

|而m_async_ops> 0

| Thread.Sleep(200)

|结束时

|

|
Ryan,
In addition to the other comments:

I would store the IAsyncResult values returned from BeginInvoke in a list,
that I then did a For Each over doing an EndInvoke on each one in turn.

Something like:

Public Delegate Sub DoSomething()

Public Shared Sub Something()
System.Threading.Thread.Sleep(TimeSpan.FromSeconds (0.5))
End Sub

Public Shared Sub Main()
Dim method As DoSomething = AddressOf Something
Dim results As New ArrayList

For index As Integer = 1 To 100
Dim result As IAsyncResult = method.BeginInvoke(Nothing,
Nothing)
results.Add(result)
Next

For Each result As IAsyncResult In results
Try
method.EndInvoke(result)
Catch ex As Exception
'' report the error but keep going...
Debug.WriteLine(ex, "End Invoke")
End Try
Next

End Sub

This allows the main thread to quietly wait until all the workers are
finished. Because the workers are finishing asynchronously the EndInvoke
will either return really quickly for completed workers or wait for busy
workers...

Note depending on the method called, you may want to store the Delegate
itself (the method variable) in the list also or as the AsyncState on the
BeginInvoke call...

--
Jay [MVP - Outlook]
..NET Application Architect, Enthusiast, & Evangelist
T.S. Bradley - http://www.tsbradley.net
"ryan" <ro*************@inval.hotmail.com> wrote in message
news:eI**************@TK2MSFTNGP09.phx.gbl...
| Hi,
| I''ve omitted a large chunk of the code for clarity but the loop below is
how
| I''m calling a delegate function asynchronously. After I start the each
call
| I''m incrementing a counter and then making the main thread sleep until the
| counter gets back to zero. The call back function for each call decrements
| the counter. Is there a better way to make the thread wait until all calls
| are complete besides using the counter? I''ve seen some things with using
an
| IAsyncResult but I''m not sure how to do that in my case since I''m making 1
| to n calls.
| Thanks,
| Ryan
|
| For iProviderIndex As Int32 = 0 To oProviders.Length - 1
| oLookupReq = New Schema.LookupRequest
| oLookup =
| CType(Activator.CreateInstance(Type.GetType(oLooku pType.class_id)),
| Schema.IPrequalLookup)
| Del = New LookupAsyncDelegate(AddressOf oLookup.GetPrequalResponse)
| Del.BeginInvoke(oLookupReq, AddressOf LookupCallback, Del)
| IncrementAsyncOps()
| Next iProviderIndex
|
| While m_async_ops > 0
| Thread.Sleep(200)
| End While
|
|


这篇关于等待异步委托调用完成的最佳方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆