- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
I am trying to run acad code from a WCF service in process. I get most everything work just fine but for some reason I get this cryptic error when I try to loop through a selection set of AcadEntity objects. The weird part is that if I place the same loop in a simple IExtensionApplication command it works fine.
Does anyone have any suggestions how to make this work? I assume something to do with wcf service behavior/acad threading model but not sure what.
Here is the full source code, note that I am not using Editor.WriteMessage because that's one of the things I cannot get working from WCF so I am relying on NLog to generate the output on the bottom of this message. If you have an idea how to make Editor.WriteMessage work from WCF I'd appreciate your help as well.
Thanks in advance,
Steve
Imports System.ServiceModel
Imports System.ServiceModel.Description
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.Interop
Imports Autodesk.AutoCAD.Interop.Common
Imports Autodesk.AutoCAD.ApplicationServices
Imports MgdAcApplication = Autodesk.AutoCAD.ApplicationServices.Application
Imports NLog
#Region "WCF SERVICE"
<ServiceContract()>
Public Interface ISelectItems
<OperationContract()>
Sub SelectItems()
End Interface
<ServiceBehavior(InstanceContextMode:=InstanceContextMode.Single, ConcurrencyMode:=ConcurrencyMode.Single)>
Public Class wcfSelectItems
Implements ISelectItems
Private log As Logger = LogManager.GetCurrentClassLogger
Public Sub SelectItems() Implements ISelectItems.SelectItems
log.Info("This will crash")
DoSelection()
End Sub
Public activeDoc As Document = MgdAcApplication.DocumentManager.MdiActiveDocument
Public Sub DoSelection()
Try
Using acDocLck As DocumentLock = activeDoc.LockDocument()
Dim td As AcadDocument = DocumentExtension.GetAcadDocument(activeDoc)
Dim ssetObj As AcadSelectionSet = td.SelectionSets.Add("SSALL0") ' creates named selection set
ssetObj.Select(AcSelect.acSelectionSetAll)
log.Trace("We have a selection of size = {0}", ssetObj.Count)
Try
For Each ent As AcadEntity In ssetObj
log.Trace("{0}", ent.ObjectName)
Next
Catch
log.Error("This is the crash: '{0}'", Err.Description)
End Try
End Using
Catch
log.Error(Err.Description)
End Try
End Sub
End Class
#End Region
Public Class clsSelectedItems
Implements IExtensionApplication
Private log As Logger = LogManager.GetCurrentClassLogger
#Region "ACAD COMMAND"
<CommandMethod("DoSelection")> _
Public Sub DoSelection_Method()
log.Info("This is OK")
DoSelection()
End Sub
#End Region
Public m_DefaultService As String = "ISelectItems"
Public m_DefaultIP As String = "127.0.0.1"
Public m_DefaultPort As String = "7200"
Public m_DefaultProtocol As String = "http"
Private m_serviceHost As ServiceHost = Nothing
Public Sub Initialize() Implements Autodesk.AutoCAD.Runtime.IExtensionApplication.Initialize
hostService(m_DefaultIP, m_DefaultPort)
End Sub
Public Sub Terminate() Implements Autodesk.AutoCAD.Runtime.IExtensionApplication.Terminate
If Not m_serviceHost Is Nothing Then
m_serviceHost.Close()
End If
End Sub
Public activeDoc As Document = MgdAcApplication.DocumentManager.MdiActiveDocument
'Do selection routine, exact same as above. This one works:
Public Sub DoSelection()
Try
Using acDocLck As DocumentLock = activeDoc.LockDocument()
Dim td As AcadDocument = DocumentExtension.GetAcadDocument(activeDoc)
Dim ssetObj As AcadSelectionSet = td.SelectionSets.Add("SSALL1") ' creates named selection set
ssetObj.Select(AcSelect.acSelectionSetAll)
log.Trace("We have a selection of size = {0}", ssetObj.Count)
Try
For Each ent As AcadEntity In ssetObj
log.Trace("{0}", ent.ObjectName)
Next
Catch
log.Error("This is the crash: '{0}'", Err.Description)
End Try
End Using
Catch
log.Error(Err.Description)
End Try
End Sub
' Set up a WCF service endpoint and start service
Public Sub hostService(ByVal _hostIP As String, ByVal _port As String)
Dim wcfEndpoint As String = String.Format("{0}://{1}:{2}/{3}", m_DefaultProtocol, _hostIP, _port, m_DefaultService)
Try
Dim baseAddress As Uri = New Uri(wcfEndpoint)
m_serviceHost = New ServiceHost(GetType(wcfSelectItems), baseAddress)
Dim binding = CreateNewHttpBinding(GetType(wcfSelectItems).FullName)
m_serviceHost.AddServiceEndpoint(GetType(ISelectItems), binding, "IAcadInProc")
Dim smb As New ServiceMetadataBehavior()
smb.HttpGetEnabled = True
m_serviceHost.Description.Behaviors.Add(smb)
Catch ex As Exception
log.Error("EX 2. {0}", ex.ToString)
End Try
m_serviceHost.Open()
log.Info("Listening on {0}", wcfEndpoint)
End Sub
'We avoid using config files for now:
Private Shared Function CreateNewHttpBinding(ByVal name As String) As WSHttpBinding
Dim result As New WSHttpBinding
result.Name = name
result.OpenTimeout = New TimeSpan(0, 1, 0)
result.ReceiveTimeout = New TimeSpan(0, 10, 0)
result.SendTimeout = New TimeSpan(0, 1, 0)
result.BypassProxyOnLocal = False
result.TransactionFlow = False
result.HostNameComparisonMode = HostNameComparisonMode.StrongWildcard
result.MaxBufferPoolSize = 2147483647
result.MaxReceivedMessageSize = 2147483647
result.MessageEncoding = WSMessageEncoding.Text
result.TextEncoding = System.Text.Encoding.UTF8
result.UseDefaultWebProxy = True
result.AllowCookies = False
result.ReaderQuotas.MaxStringContentLength = 2147483647
result.ReaderQuotas.MaxDepth = 12
result.ReaderQuotas.MaxArrayLength = 16384
result.ReaderQuotas.MaxBytesPerRead = 4096
result.ReaderQuotas.MaxNameTableCharCount = 16384
result.ReliableSession.Ordered = False
result.ReliableSession.InactivityTimeout = New TimeSpan(0, 10, 0)
result.ReliableSession.Enabled = False
result.Security.Mode = SecurityMode.None
result.Security.Transport.ClientCredentialType = HttpClientCredentialType.None
result.Security.Message.ClientCredentialType = MessageCredentialType.None
Return (result)
End Function
End Class
OUTPUT:
Info clsSelectedItems Listening on http://127.0.0.1:7200/ISelectItems
Info wcfSelectItems This will crash
Trace wcfSelectItems We have a selection of size = 200
Error wcfSelectItems This is the crash: 'Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED))'
Info clsSelectedItems This is OK
Trace clsSelectedItems We have a selection of size = 200
Trace clsSelectedItems AcDbText
Trace clsSelectedItems AcDbViewport
Trace clsSelectedItems AcDbViewport
% <--------------ETC. CUT------------->%
Solved! Go to Solution.