对 WCF 的 WPF 服务调用无法访问已释放的对象

Posted

技术标签:

【中文标题】对 WCF 的 WPF 服务调用无法访问已释放的对象【英文标题】:WPF Service Call to WCF Cannot access a disposed object 【发布时间】:2015-03-16 17:15:13 【问题描述】:

我们有一个从 WCF 服务返回数据的 WPF 应用程序。

下面的代码会间歇性地抛出“无法作为已处理对象访问”错误 - 通常是在一个更新序列已经成功完成之后。

即使在每次通话时关闭服务并启动新服务也无济于事。有什么想法吗?

谢谢...

 Private Sub Reports_BalanceSheet_DoWork(sender As Object, e As DoWorkEventArgs)
    Try
        Dim vUpdate As New UpdateDelegate(AddressOf Reports_BalanceSheet_UpdateDB_Delegate)
        Dim vName As String = ReportName

        vService = New Service1Client

        Dim vID As Integer = 0
        If NewRecord = True Then
            Dim vRows As Integer = vService.ReturnScalarInteger("SELECT COUNT(Form_ID) From Balance_Sheet_Templates", Current_HOA_ID)
            If vRows > 0 Then
                vID = NullInteger(vService.ReturnScalarInteger("SELECT MAX(Form_ID) FROM Balance_Sheet_Templates", Current_HOA_ID))
            End If
            vID += 1
            'Save the form name
            strSQL = "INSERT INTO Balance_Sheet_Templates(Form_ID, Category_Type, Category_ID,  Form_Name) VALUES ("
            strSQL += "'" & vID & "', "
            strSQL += "'1', "
            strSQL += "'1', "
            strSQL += "'" & vName & "')"
            If vService.InsertDataHOA(strSQL, "Reports_BalanceSheet_Page 2466 " & Current_HOA_Name, Current_HOA_ID) = False Then
                IsError = True
                Dim Error1() As Object = "There was an error updating the record"
                Dispatcher.BeginInvoke(vUpdate, New Object() Error1)
                Exit Sub
            End If


        Else

            vID = FormID
            strSQL = "DELETE Balance_Sheet_Templates WHERE Form_ID = " & vID
            If vService.InsertDataHOA(strSQL, "Reports_BalanceSheet_Page 2455 " & Current_HOA_Name, Current_HOA_ID) = False Then
                IsError = True
                Dim Error1() As Object = "There was an error updating the record"
                Dispatcher.BeginInvoke(vUpdate, New Object() Error1)
                Exit Sub
            End If
        End If




        Dim Update1() As Object = "Saving the report defaults... Please wait..."
        Dispatcher.BeginInvoke(vUpdate, New Object() Update1)
        For Each Row As DataRow In ReportDT.Rows
            strSQL = "INSERT INTO Balance_Sheet_Templates (Form_ID, Category_Type, Category_ID, Form_Name) VALUES ("
            strSQL += "'" & vID & "', "
            strSQL += "'1', "
            strSQL += "'" & Row("ID") & "', "
            strSQL += "'" & vName & "')"
            If vService.InsertDataHOA(strSQL, "Reports_BalanceSheet_Page 2417 " & Current_HOA_Name, Current_HOA_ID) = False Then
                IsError = True
                Dim Error1() As Object = "There was an error updating the record"
                Dispatcher.BeginInvoke(vUpdate, New Object() Error1)
                Exit Sub
            End If
        Next



        Dim Update2() As Object = "Saving the revenue categories... Please wait..."
        Dispatcher.BeginInvoke(vUpdate, New Object() Update2)
        For Each Row As DataRow In RevenueDT.Rows
            strSQL = "INSERT INTO Balance_Sheet_Templates (Form_ID, Category_Type, Category_ID, Position, Key_String) VALUES ("
            strSQL += "'" & vID & "', "
            strSQL += "'3', "
            strSQL += "'" & Row("ID") & "', "
            strSQL += "'" & Row("Position") & "', "
            strSQL += "'" & SubmitText(Row("Name")) & "')"
            If vService.InsertDataHOA(strSQL, "Reports_BalanceSheet_Page 2434 " & Current_HOA_Name, Current_HOA_ID) = False Then
                IsError = True
                Dim Error1() As Object = "There was an error updating the record"
                Dispatcher.BeginInvoke(vUpdate, New Object() Error1)
                Exit Sub
            End If
        Next



        Dim Update3() As Object = "Saving the revenue data... Please wait..."
        Dispatcher.BeginInvoke(vUpdate, New Object() Update3)
        For Each Row As DataRow In RevenueNomDT.Rows
            strSQL = "INSERT INTO Balance_Sheet_Templates (Form_ID, Category_Type, Category_ID, Position, Cat_Name_ID, Nom_Code, Nom_Name) VALUES ("
            strSQL += "'" & vID & "', "
            strSQL += "'4', "
            strSQL += "'" & Row("ID") & "', "
            strSQL += "'" & Row("Position") & "', "
            strSQL += "'" & Row("CatID") & "', "
            strSQL += "'" & Row("NomCode") & "', "
            strSQL += "'" & SubmitText(Row("NomName")) & "')"
            If vService.InsertDataHOA(strSQL, "Reports_BalanceSheet_Page 2453 " & Current_HOA_Name, Current_HOA_ID) = False Then
                IsError = True
                Dim Error1() As Object = "There was an error updating the record"
                Dispatcher.BeginInvoke(vUpdate, New Object() Error1)
                Exit Sub
            End If
        Next



        Dim Update4() As Object = "Saving the expenses categories... Please wait..."
        Dispatcher.BeginInvoke(vUpdate, New Object() Update4)
        For Each Row As DataRow In ExpensesDT.Rows
            strSQL = "INSERT INTO Balance_Sheet_Templates (Form_ID, Category_Type, Category_ID, Position, Key_String) VALUES ("
            strSQL += "'" & vID & "', "
            strSQL += "'5', "
            strSQL += "'" & Row("ID") & "', "
            strSQL += "'" & Row("Position") & "', "
            strSQL += "'" & SubmitText(Row("Name")) & "')"
            If vService.InsertDataHOA(strSQL, "Reports_BalanceSheet_Page 2472 " & Current_HOA_Name, Current_HOA_ID) = False Then
                IsError = True
                Dim Error1() As Object = "There was an error updating the record"
                Dispatcher.BeginInvoke(vUpdate, New Object() Error1)
                Exit Sub
            End If
        Next



        Dim Update5() As Object = "Saving the expenses data... Please wait..."
        Dispatcher.BeginInvoke(vUpdate, New Object() Update5)
        For Each Row As DataRow In ExpensesNomDT.Rows
            strSQL = "INSERT INTO Balance_Sheet_Templates (Form_ID, Category_Type, Category_ID, Position, Cat_Name_ID, Nom_Code, Nom_Name) VALUES ("
            strSQL += "'" & vID & "', "
            strSQL += "'6', "
            strSQL += "'" & Row("ID") & "', "
            strSQL += "'" & Row("Position") & "', "
            strSQL += "'" & Row("CatID") & "', "
            strSQL += "'" & Row("NomCode") & "', "
            strSQL += "'" & SubmitText(Row("NomName")) & "') "
            If vService.InsertDataHOA(strSQL, "Reports_BalanceSheet_Page 2491 " & Current_HOA_Name, Current_HOA_ID) = False Then
                IsError = True
                Dim Error1() As Object = "There was an error updating the record"
                Dispatcher.BeginInvoke(vUpdate, New Object() Error1)
                Exit Sub
            End If
        Next




        Dim Update6() As Object = "Saving the assets categories... Please wait..."
        Dispatcher.BeginInvoke(vUpdate, New Object() Update6)
        For Each Row As DataRow In ResIncomeDT.Rows
            strSQL = "INSERT INTO Balance_Sheet_Templates (Form_ID, Category_Type, Category_ID, Position, Key_String) VALUES ("
            strSQL += "'" & vID & "', "
            strSQL += "'7', "
            strSQL += "'" & Row("ID") & "', "
            strSQL += "'" & Row("Position") & "', "
            strSQL += "'" & SubmitText(Row("Name")) & "')"
            If vService.InsertDataHOA(strSQL, "Reports_BalanceSheet_Page 2509 " & Current_HOA_Name, Current_HOA_ID) = False Then
                IsError = True
                Dim Error1() As Object = "There was an error updating the record"
                Dispatcher.BeginInvoke(vUpdate, New Object() Error1)
                Exit Sub
            End If
        Next




        Dim Update7() As Object = "Saving the assets data... Please wait..."
        Dispatcher.BeginInvoke(vUpdate, New Object() Update7)
        For Each Row As DataRow In ResIncNomDT.Rows
            strSQL = "INSERT INTO Balance_Sheet_Templates (Form_ID, Category_Type, Category_ID, Position, Cat_Name_ID, Nom_Code, Nom_Name) VALUES ("
            strSQL += "'" & vID & "', "
            strSQL += "'8', "
            strSQL += "'" & Row("ID") & "', "
            strSQL += "'" & Row("Position") & "', "
            strSQL += "'" & Row("CatID") & "', "
            strSQL += "'" & Row("NomCode") & "', "
            strSQL += "'" & Row("NomName") & "') "
            If vService.InsertDataHOA(strSQL, "Reports_BalanceSheet_Page 2529 " & Current_HOA_Name, Current_HOA_ID) = False Then
                IsError = True
                Dim Error1() As Object = "There was an error updating the record"
                Dispatcher.BeginInvoke(vUpdate, New Object() Error1)
                Exit Sub
            End If
        Next




        Dim Update8() As Object = "Saving the liability categories... Please wait..."
        Dispatcher.BeginInvoke(vUpdate, New Object() Update8)
        For Each Row As DataRow In ResExpensesDT.Rows
            strSQL = "INSERT INTO Balance_Sheet_Templates (Form_ID, Category_Type, Category_ID, Position, Key_String) VALUES ("
            strSQL += "'" & vID & "', "
            strSQL += "'9', "
            strSQL += "'" & Row("ID") & "', "
            strSQL += "'" & Row("Position") & "', "
            strSQL += "'" & SubmitText(Row("Name")) & "')"
            If vService.InsertDataHOA(strSQL, "Reports_BalanceSheet_Page 2548 " & Current_HOA_Name, Current_HOA_ID) = False Then
                IsError = True
                Dim Error1() As Object = "There was an error updating the record"
                Dispatcher.BeginInvoke(vUpdate, New Object() Error1)
                Exit Sub
            End If
        Next




        Dim Update9() As Object = "Saving the liability data... Please wait..."
        Dispatcher.BeginInvoke(vUpdate, New Object() Update9)
        For Each Row As DataRow In ResExpNomDT.Rows
            strSQL = "INSERT INTO Balance_Sheet_Templates (Form_ID, Category_Type, Category_ID, Position, Cat_Name_ID, Nom_Code, Nom_Name) VALUES ("
            strSQL += "'" & vID & "', "
            strSQL += "'10', "
            strSQL += "'" & Row("ID") & "', "
            strSQL += "'" & Row("Position") & "', "
            strSQL += "'" & Row("CatID") & "', "
            strSQL += "'" & Row("NomCode") & "', "
            strSQL += "'" & Row("NomName") & "') "
            If vService.InsertDataHOA(strSQL, "Reports_BalanceSheet_Page 2566 " & Current_HOA_Name, Current_HOA_ID) = False Then
                IsError = True
                Dim Error1() As Object = "There was an error updating the record"
                Dispatcher.BeginInvoke(vUpdate, New Object() Error1)
                Exit Sub
            End If
        Next




    Catch ex As Exception
        EmailError(ex, False)
        IsError = True
    Finally
        If Not vService Is Nothing Then
            vService.Close()
            vService = Nothing
        End If
    End Try
End Sub



Private Sub Reports_BalanceSheet_WorkCompleted(sender As Object, e As RunWorkerCompletedEventArgs)
    Try
        If IsError = True Then
            AppBoxError("There was an error updating the record!")
            Exit Sub
        End If
        PageStatusBarLoaded(Reports_BalanceSheet_Grid, "Template was successfully saved...")
        PageStatusBarRightChangeText(Reports_BalanceSheet_Grid, "Template updated...")
        Dim SaveUpdateButton As Button = Reports_BalanceSheet_Grid.FindName("BalanceSheet_SaveUpdateButton")
        If NewRecord = True Then
            SaveUpdateButton.IsEnabled = False
            SaveUpdateButton.Content = ReturnToolBarImageGrey("Record_Insert.png")
        End If
    Catch ex As Exception
        EmailError(ex)
    End Try
End Sub



Private Sub Reports_BalanceSheet_UpdateDB_Delegate(ByVal x() As Object)
    Try
        PageStatusBarRightChangeText(Reports_BalanceSheet_Grid, x(0).ToString)
    Catch ex As Exception
        EmailError(ex)
    End Try
End Sub

返回的错误

Cannot access a disposed object.

对象名称:'System.ServiceModel.Channels.HttpsChannelFactory`1+HttpsRequestChannel[System.ServiceModel.Channels.IRequestChannel]'。

服务器堆栈跟踪: 在 System.ServiceModel.Channels.CommunicationObject.ThrowIfDisposedOrNotOpen() 在 System.ServiceModel.Channels.HttpChannelFactory`1.HttpRequestChannel.HttpChannelRequest.SendRequest(消息消息,TimeSpan 超时) 在 System.ServiceModel.Channels.RequestChannel.Request(消息消息,TimeSpan 超时) 在 System.ServiceModel.Dispatcher.RequestChannelBinder.Request(消息消息,TimeSpan 超时) 在 System.ServiceModel.Channels.ServiceChannel.Call(字符串操作,布尔单向,ProxyOperationRuntime 操作,Object[] 输入,Object[] 输出,TimeSpan 超时) 在 System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage 方法调用,ProxyOperationRuntime 操作) 在 System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage 消息)

在 [0] 处重新抛出异常: 在 System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg,IMessage retMsg) 在 System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData,Int32 类型) 在 HOA_Manager_Client_04.ServiceReference1.IService1.InsertDataHOA(字符串 strSQL,字符串 LineNo,字符串 HOAID) 在 HOA_Manager_Client_04.ServiceReference1.Service1Client.InsertDataHOA(字符串 strSQL,字符串 LineNo,字符串 HOAID) 在 HOA_Manager_Client_04.Reports_BalanceSheet_Page.Reports_BalanceSheet_DoWork(Object sender, DoWorkEventArgs e)

【问题讨论】:

【参考方案1】:

在整个应用程序的每个页面中都定义了vService

Private strSQL As String
Private vService As Service1Client

并在需要时创建为 New。显然有些东西也在同时使用和关闭它,所以我刚刚创建了一个全新的服务

 Private Sub Reports_BalanceSheet_DoWork(sender As Object, e As DoWorkEventArgs)
    Dim vService1 As New Service1Client
    Try
        Dim vUpdate As New UpdateDelegate(AddressOf Reports_BalanceSheet_UpdateDB_Delegate)
        Dim vName As String = ReportName

        ' vService = New Service1Client

并将每个更新实例都更改为那个 - 到目前为止它似乎正在工作。奇怪的是,这是整个应用程序中唯一抛出此错误的地方

【讨论】:

以上是关于对 WCF 的 WPF 服务调用无法访问已释放的对象的主要内容,如果未能解决你的问题,请参考以下文章

如何从同一 WPF 应用程序托管的 WCF 服务调用 WPF 应用程序中的方法?

WPF如何调用WCF对数据增删改查的服务

无法使用 WCF 调用具有基本身份验证的 Web 服务

WCF , WPF,MVC,有啥不同

WCF , WPF,MVC,有啥不同

WPF 应用程序托管 WCF 访问冲突