Есть проблема с генерацией событий для
клиентов удаленного объекта в VB .NET.
При вызове метода на сервере, инициируется событие, например так:
public sub Submit()
raiseevent MySubmitEvent( me, new eventargs() )
end sub
А клиенты, которые имеют ссылку на удаленный объект, получают это
событие. Проблема в том, что если один из клиентов отключается аварийно (без
соответствующего вызова RemoveHandler), то остальные клиенты при
последующей генерации этого события получают исключение.
Я видел пример на C#, как избежать такой ситуации. Там на сервере событие
инициировалось для каждого клиента отдельно в блоке try...catch:
public void Submit(){
if( mysubmitEventHandler != null ){
delegate[] invList = mysubmitEventHandler.GetInvocationList()
for each delegate d in invList{
try
d.Invoke( this, new eventargs )
catch
}
}
}
Можно ли как-нибудь проделать такое же и в VB.NET?
Yадо объявлять переменную без ключевого слова Еvent. Только
клиенты теперь подписываются на событие сервера, при помощи метода
Delegate.Combine( ... ), а не AddHandler. По крайней мере, это
работает.
Сервер:
public class CMyRemote
inherits MarshalByRefObject
public delegate sub mysubmitEventHandler( sender as Object, e as EventArgs )
public MySubmitEvent as mysubmitEventHandler
public sub Submit()
if not( MySubmitEvent is nothing ) then
dim aInvList() as [delegate] = MySubmitEvent.GetInvocationList()
dim d as [delegate]
for each d in aInvList
try
' вызывается для каждого клиента, подписавшегося на событие
' если один из клиентов аварийно завершит свою работу, то будет
инициировано исключение...
d.DynamicInvoke( new Object(){ me, new eventargs() } )
catch e as Exception
MySubmitEvent = system.Delegate.Remove( MySubmitEvent, d )
end try
next
end if
end sub
End Class
Клиент:
public class MyClient
inherits MarshalByRefObject
public shared sub Main()
ConfigureRemoteServer()
dim ro as New MyRemoteAssm.CMyRemote
dim d as MyRemoteAssm.CMyRemote.mysubmitEventHandler = AddressOf me.MyCallbackFunc
ro.MySubmitEvent = system.Delegate.Combine( ro.MySubmitEvent, d )
console.WriteLine( "подключение к удаленному объекту прошло успешно!...")
ro.Submit()
console.ReadLine()
ro.MySubmitEvent = system.Delegate.Remove( ro.MySubmitEvent, d )
End Sub
public sub ConfigureRemoteServer()
RemotingConfiguration.Configure( "..\ClientConsole.exe.config" )
End Sub
public sub MyCallbackFunc( o as Object, e as EventArgs )
console.WriteLine( "событие получено..." )
End Sub
End Class