Nous avons un problème dans notre application Silverlight qui utilise WCF et Entity Framework, où nous devons piéger l'événement lorsqu'un utilisateur ferme l'application en fermant la page Web ou le navigateur au lieu de la fermeture de l'application Silverlight. C'est afin de vérifier si des changements ont été faits, auquel cas nous demandons à l'utilisateur s'il veut enregistrer avant de partir.Utilisation de dispatchertimer en combinaison avec un appel asynchrone
Nous avons été en mesure d'accomplir la partie qui consiste à piéger la fermeture de la page web: nous avons écrit du code dans l'objet application dont la page web appelle une méthode dans l'objet application silverlight. Le problème commence lorsque dans cette méthode, nous effectuons un appel asynchrone au service Web pour vérifier si des modifications ont eu lieu (IsDirty). Nous utilisons un DispatcherTimer pour vérifier le retour de l'appel asynchrone. Le problème est que l'appel asynchrone ne se termine jamais (en mode de débogage, il ne finit jamais dans la méthode _BfrServ_Customer_IsDirtyCompleted), alors qu'il fonctionnait correctement avant d'ajouter cette nouvelle fonctionnalité.
Vous trouverez ci-dessous le code que nous utilisons.
Je suis nouveau à l'écriture de minuteries en combinaison avec un appel asynchrone, donc je peux faire quelque chose de mal, mais je ne peux pas comprendre quoi. J'ai essayé d'autres choses aussi, mais nous avons sans succès ..
====================== CODE =========== ===================================
''# Code in the application object
Public Sub New()
InitializeComponent()
RegisterOnBeforeUnload()
_DispatcherTimer.Interval = New TimeSpan(0, 0, 0, 0, 500)
End Sub
Public Sub RegisterOnBeforeUnload()
''# Register Silverlight object for availability in Javascript.
Const scriptableObjectName As String = "Bridge"
HtmlPage.RegisterScriptableObject(scriptableObjectName, Me)
''# Start listening to Javascript event.
Dim pluginName As String = HtmlPage.Plugin.Id
HtmlPage.Window.Eval(String.Format("window.onbeforeunload = function() {{ var slApp = document.getElementById('{0}'); var result = slApp.Content.{1}.OnBeforeUnload(); if(result.length > 0)return result;}}", pluginName, scriptableObjectName))
End Sub
Public Function OnBeforeUnload() As String
Dim userControls As List(Of UserControl) = New List(Of UserControl)
Dim test As Boolean = True
If CType(Me.RootVisual, StartPage).LayoutRoot.Children.Item(0).GetType().Name = "MainPage" Then
If Not CType(CType(Me.RootVisual, StartPage).LayoutRoot.Children.Item(0), MainPage).FindName("Tab") Is Nothing Then
If CType(CType(Me.RootVisual, StartPage).LayoutRoot.Children.Item(0), MainPage).FindName("Tab").Items.Count >= 1 Then
For Each item As TabItem In CType(CType(Me.RootVisual, StartPage).LayoutRoot.Children.Item(0), MainPage).Tab.Items
If item.Content.GetType().Name = "CustomerDetailUI"
_Item = item
WaitHandle = New AutoResetEvent(False)
DoAsyncCall()
Exit
End If
Next
End If
End If
End If
If _IsDirty = True Then
Return "Do you want to save before leaving."
Else
Return String.Empty
End If
End Function
Private Sub DoAsyncCall()
_Item.Content.CheckForIsDirty(WaitHandle) ''# This code resides in the CustomerDetailUI UserControl - see below for the code
End Sub
Private Sub _DispatcherTimer_Tick(ByVal sender As Object, ByVal e As System.EventArgs) Handles _DispatcherTimer.Tick
If Not _Item.Content._IsDirtyCompleted = True Then
Exit Sub
End If
_DispatcherTimerRunning = False
_DispatcherTimer.Stop()
ProcessAsyncCallResult()
End Sub
Private Sub ProcessAsyncCallResult()
_IsDirty = _Item.Content._IsDirty
End Sub
''# CustomerDetailUI code
Public Sub CheckForIsDirty(ByVal myAutoResetEvent As AutoResetEvent)
_AutoResetEvent = myAutoResetEvent
_BfrServ.Customer_IsDirtyAsync(_Customer) ''# This method initiates asynchroneous call to the web service - all the details are not shown here
_AutoResetEvent.WaitOne()
End Sub
Private Sub _BfrServ_Customer_IsDirtyCompleted(ByVal sender As Object, ByVal e As BFRService.Customer_IsDirtyCompletedEventArgs) Handles _BfrServ.Customer_IsDirtyCompleted
If _IsDirtyFromRefesh Then
_IsDirtyFromRefesh = False
If e.Result = True Then
Me.Confirm("This customer has been modified. Are you sure you want to refresh your data ? " & vbNewLine & " Your changes will be lost.", "Yes", "No", Message.CheckIsDirtyRefresh)
End If
Busy.IsBusy = False
Else
If e.Result = True Then
_IsDirty = True
Me.Confirm("This customer has been modified. Would you like to save?", "Yes", "No", Message.CheckIsDirty)
Else
Me.Tab.Items.Remove(Me.Tab.SelectedItem)
Busy.IsBusy = False
End If
End If
_IsDirtyCompleted = True
_AutoResetEvent.Set()
End Sub
Bienvenue dans SO, veuillez prendre quelques minutes pour lire la FAQ et la documentation Markdown (un synoptique utile est disponible dans la marge de droite lors de la modification d'une question). – AnthonyWJones