У нас есть проблема в нашем приложении Silverlight, которое использует WCF и Entity Framework, где нам нужно перехватывать событие всякий раз, когда пользователь закрывает приложение, закрывая веб-страницу или браузер вместо закрытия приложения silverlight. Это делается для того, чтобы проверить, были ли внесены какие-либо изменения, и в этом случае мы спросим пользователя, хочет ли он сохранить, прежде чем уйти.
Мы смогли выполнить часть, заключающуюся в захвате закрытия веб-страницы: мы написали некоторый код в объекте приложения, в котором веб-страница вызывает метод в объекте приложения silverlight. Проблема начинается, когда в этом методе мы выполняем асинхронный вызов веб-службы, чтобы проверить, произошли ли изменения (IsDirty). Мы используем DispatcherTimer для проверки возврата асинхронного вызова. Проблема состоит в том, что асинхронный вызов никогда не завершается (в режиме отладки он никогда не заканчивается в методе _BfrServ_Customer_IsDirtyCompleted), в то время как он работал нормально до того, как мы добавили эту новую функциональность.
Ниже вы найдете код, который мы используем.
Я новичок в написании таймеров в сочетании с асинхронным вызовом, поэтому я могу делать что-то не так, но я не могу понять, что. Я пробовал и другие вещи, но мы безуспешно ..
====================== КОД ======================= ======================
''# 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