Silverlight 将Dispatchermer与异步调用结合使用
使用WCF和实体框架的Silverlight应用程序中存在一个问题,每当用户通过关闭网页或浏览器而不是关闭Silverlight应用程序关闭应用程序时,我们都需要捕获事件。这是为了验证是否进行了任何更改,在这种情况下,我们会询问用户是否希望在离开前保存 我们能够完成捕获网页关闭的部分:我们在应用程序对象中编写了一些代码,让网页在silverlight应用程序对象中调用一个方法。在该方法中,当我们对Web服务执行异步调用以验证是否发生了更改(IsDirty)时,问题就开始了。我们正在使用Dispatcher来检查异步调用的返回。问题是异步调用永远不会完成(在调试模式下,它永远不会进入_BfrServ_Customer_IsDirtyCompleted方法),而在我们添加此新功能之前,它通常工作正常 下面是我们正在使用的代码 我对结合异步调用编写计时器还不熟悉,所以我可能做错了什么,但我不知道是什么原因。我也尝试过其他的事情,但没有成功 ===========================代码==============================================Silverlight 将Dispatchermer与异步调用结合使用,silverlight,dispatchertimer,Silverlight,Dispatchertimer,使用WCF和实体框架的Silverlight应用程序中存在一个问题,每当用户通过关闭网页或浏览器而不是关闭Silverlight应用程序关闭应用程序时,我们都需要捕获事件。这是为了验证是否进行了任何更改,在这种情况下,我们会询问用户是否希望在离开前保存 我们能够完成捕获网页关闭的部分:我们在应用程序对象中编写了一些代码,让网页在silverlight应用程序对象中调用一个方法。在该方法中,当我们对Web服务执行异步调用以验证是否发生了更改(IsDirty)时,问题就开始了。我们正在使用Dispa
''# 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
您的问题是DispatchTimer试图在等待阻塞的同一线程上执行代码。因此它无法传递滴答声 我不太清楚你为什么需要计时器。为什么不直接在调用
OnBeforeUnload
时阻塞UI线程(事实上您已经这样做了)。然后让异步回调函数在分配了\u IsDirty
的值后设置等待句柄
使用消息框跟随等待。您的问题是DispatchTimer试图在等待阻塞的同一线程上执行代码。因此它无法传递滴答声 我不太清楚你为什么需要计时器。为什么不直接在调用
OnBeforeUnload
时阻塞UI线程(事实上您已经这样做了)。然后让异步回调函数在分配了\u IsDirty
的值后设置等待句柄
使用消息框跟随等待。欢迎使用SO,请花几分钟时间阅读常见问题解答和降价文档(编辑问题时,右侧空白处有一个有用的语法)。欢迎使用SO,请花几分钟时间阅读常见问题解答和降价文档(编辑问题时,可在右边空白处找到有用的语法)。