Oto podstawowy sens mojego problemu:NET: Problem z podnoszeniem i obsługi zdarzeń za pomocą AppDomains
- Moje główne klasy Okno instancję klasy A.
- Klasa A Klasa B instancję w wtórnego AppDomain.
- Klasa B podnosi wydarzenie, a klasa A skutecznie radzi sobie z wydarzeniem.
- Klasa A podnosi własne wydarzenie.
Problem: W kroku 4, gdy klasa A podnosi własne zdarzenie z metody obsługi zdarzeń, które złowionych zdarzenie Klasa B, tym zdarzenie jest wywoływane; Jednak program obsługi subskrypcji w klasie okna nigdy nie jest wywoływany.
Nie ma żadnych wyjątków. Jeśli usuniemy pomocniczą domenę aplikacji, zdarzenie zostanie obsłużone bez problemu.
Czy ktoś wie, dlaczego to nie działa? Czy istnieje inny sposób, aby to działało bez użycia wywołania zwrotnego?
Myślę, jeśli cokolwiek, problem będzie występować w kroku 3 zamiast kroku 4.
Oto próbka prawdziwy kod do zilustrowania problemu:
Class Window1
Private WithEvents _prog As DangerousProgram
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button1.Click
_prog = New DangerousProgram()
_prog.Name = "Bad Program"
End Sub
Private Sub MyEventHandler(ByVal sender As Object, ByVal e As NameChangedEventArgs) Handles _prog.NameChanged
TextBox1.Text = "Program's name is now: " & e.Name
End Sub
End Class
<Serializable()> _
Public Class DangerousProgram
Private _appDomain As AppDomain
Private WithEvents _dangerousProgram As Program
Public Event NameChanged(ByVal sender As Object, ByVal e As NameChangedEventArgs)
Public Sub New()
// DangerousPrograms are created inside their own AppDomain for security.
_appDomain = AppDomain.CreateDomain("AppDomain")
Dim assembly As String = System.Reflection.Assembly.GetEntryAssembly().FullName
_dangerousProgram = CType(_
_appDomain.CreateInstanceAndUnwrap(assembly, _
GetType(Program).FullName), Program)
End Sub
Public Property Name() As String
Get
Return _dangerousProgram.Name
End Get
Set(ByVal value As String)
_dangerousProgram.Name = value
End Set
End Property
Public Sub NameChangedHandler(ByVal sender As Object, ByVal e As NameChangedEventArgs) Handles _dangerousProgram.NameChanged
Debug.WriteLine(String.Format("Caught event in DangerousProgram. Program name is {0}.", e.Name))
Debug.WriteLine("Re-raising event...")
RaiseEvent NameChanged(Me, New NameChangedEventArgs(e.Name))
End Sub
End Class
<Serializable()> _
Public Class Program
Inherits MarshalByRefObject
Private _name As String
Public Event NameChanged(ByVal sender As Object, ByVal e As NameChangedEventArgs)
Public Property Name() As String
Get
Return _name
End Get
Set(ByVal value As String)
_name = value
RaiseEvent NameChanged(Me, New NameChangedEventArgs(_name))
End Set
End Property
End Class
<Serializable()> _
Public Class NameChangedEventArgs
Inherits EventArgs
Public Name As String
Public Sub New(ByVal newName As String)
Name = newName
End Sub
End Class
Podoba mi się Twoja sugestia. Twoje ostatnie oświadczenie jest doskonałym podsumowaniem. Dzięki! –
Świetne rozwiązanie! Alternatywnie możemy zezwolić ** AD2 ** na posiadanie "RealProxy" ** X ** i subskrybowanie ** X.MyEvent ** od ** AD1 **. Wykonanie tego będzie wymagało, aby funkcja obsługi zdarzeń ** A ** została zebrana, co zostało przekazane do ** AD2 **. Kiedy zdarzenie zostanie uruchomione, ** AD2 ** używa teraz 'TransparentProxy' programu obsługi zdarzenia. To jest po prostu odwrotność rozwiązania, więc może być przydatne w zależności od tego, kto (która domena aplikacji) musi być właścicielem "RealProxy" zdarzenia. –