Some general questions

Latest post 09-16-2008 4:06 AM by wangym. 30 replies.
  • 08-13-2008 9:34 AM In reply to

    • Gary
    • Top 10 Contributor
    • Joined on 07-13-2006
    • Posts 307

    Re: Some general questions

    The Entry point attribute, etc... would be excellent additions to ProxyGen, but unfortunately they are not inclluded in ProxyGen's capabilities.

    A UI abstraction tool is probably not a likely addition because it would typically be better to create your object model to be independent of the UI and to be an abstraction closer to the core of your application's functionality.

     

  • 08-27-2008 4:58 AM In reply to

    Re: Some general questions

    Hi, Gary,
    I try to control host's UI from vsta through an extra layer.
    But I got an exception, runtime told me try to visit control not from the thread created it.(non-destructive debugging)
    That is, do I have to Invoke every call in the extra layer?
    Or is there any configuration make vsta addin view call the function from main thread?
    I found when run my host application directly (not debug with vs), the exception seems not exists.
    I don't know why.

    I noticed your post about FrameworkElementAdapters.
    Can I use this adapter with vsta now?

    Thanks.
  • 08-27-2008 10:07 AM In reply to

    • Gary
    • Top 10 Contributor
    • Joined on 07-13-2006
    • Posts 307

    Re: Some general questions

    There is no attribute that proxygen will use to mark the entry point.

    Melody could add that to the 'autoproxygen' she is working on.

    I am not aware of a tool that generates a facade of UI. 

    It certainly would be possible to generate a 'first draft' facade of UI for part of the object model, but a good object model will usually focus on the application's data objects and state rather than the application's UI layer.  The UI layer may change, but the underlying data model is usually stable and best represents the application's functionality.

     

     

  • 08-27-2008 10:40 AM In reply to

    • Gary
    • Top 10 Contributor
    • Joined on 07-13-2006
    • Posts 307

    Re: Some general questions

    Out of process debug hosts the AddIn in a different process.

    A quick ‘fix’ for this is to set a property on UI class (ie: ShapeAppForm):  CheckForIllegalCrossThreadCalls = false;

     

      /// <summary>

            /// Internal constructor for this form.

            /// </summary>

            /// <param name="application">The active ShapeApp application instance.</param>

            internal ShapeAppForm(Application application)

            {

                èCheckForIllegalCrossThreadCalls = false;

                InitializeComponent();

                this.application = application;

     

                sizeDialog = new SizeDialog();

                locationDialog = new LocationDialog();

            }

     

    Re-build, try debugging now and there’s no error. 

    But the CheckForIllegalCrossThreadCalls fine print saays cross thread calls to winform UI “often leads to unpredictable results”

    This fine qualifier means that when ISVs want to support robust OOP debugging with VSTA IDE, they need to use thread safe calls on their UI.

    This requires the host to do more work if the host OM allows AddIn to manipulate host UI. There are two things the host needs to do.

    1.       Make sure all the UI operations are carried out in the main UI thread. For example ,

    public bool Visible

            {

                get

                {

                    return form.Visible;

                }

                set

                {

                    if (form.InvokeRequired)

                    {

                        VisibleDelegate vd = delegate()

                        {

                            form.Visible = value;   

                        };

                        form.Invoke(vd);

                    }

                    else

                    {

                        form.Visible = value;

                    }

                }

            }

            private delegate void VisibleDelegate();

     

    2.       When executing macros, you need to call it from a different thread other than the main thread. Otherwise, the main thread is blocked and cannot service the Macro’s callback request and we’ll get a deadlock. For example,

           

    internal void ExecuteMacro(string macroName)

            {

                Thread t = new Thread(() =>

                {

                    ExecuteMacroInternal(macroName); // The original ExecuteMacro function is called here.

                });

                t.SetApartmentState(Thread.CurrentThread.GetApartmentState());

                t.Start();

                // Do not call t.Join(); Otherwise it'll block and the host will be frozen.

            }

     

    The reason for this limitation is because System.AddIn.dll that VSTA relies on uses .Net remoting IPC channel to communicate between AddIn and Host. IPC channel uses .net thread-pool threads to serve remote method calls. So when AddIn calls Host API, the call will be executed on some thread-pool thread other than the main thread. This problem only shows up in out-of-proc scenario because .Net remoting within the same process has some optimization that doesn’t use the thread-pool threads.

     These cross-thread provisions were added back into the VSTA 2.0 samples for the final release bits

    (http://www.summsoft.com/files/folders/vstasdk/entry1238.aspx).

  • 08-31-2008 10:30 PM In reply to

    Re: Some general questions

    Thanks, Gary,
    I understand you focus more in data object than UI, but sometime UI is also the important part  that user want to customize.
    I have another question, how to expose COM component from .net host application to vsta addin? I wish to avoid the proxy code. Give vsta addin an IntPtr?
  • 09-02-2008 12:23 PM In reply to

    • Gary
    • Top 10 Contributor
    • Joined on 07-13-2006
    • Posts 307

    Re: Some general questions

    >>sometime UI is also important part that user want to customize.

    Yes, that's true.  For UI customization, you will have to abstract the UI that may be customized as part of the object model.

    I've just added a new sample (to the downloads) that demonstrates the use of a COM 'object model agent' to pass along the IDispatch ptr of the host's COM object model to the vsta Add-in. 

    Hope you like it:  ShapeAppMFCwithOMAgent sample

    [http://www.summsoft.com/files/folders/vsta_samples/entry1254.aspx]

  • 09-07-2008 9:58 AM In reply to

    Re: Some general questions

    Hi Gary,
    I have a deadlock question.
    I have a timer on my host application and I want trigger timer event to vsta addin.
    code in hostapp:
    -------------
    void OnTimer()
    {
           if (OnTMTimerEventHandler != null)
           {
                   TMTimerEventArgs ea = new TMTimerEventArgs(e.tmCurrentTime);
                    OnTMTimerEventHandler(this, ea);
           }
    }
    MainFormWrapper.Text
    {
       if (mainform.InvokerRequired)
           mainform.Invoke(...SetText, value)
       else
           SetText(value)
    }
    -----------------
    code in vsta
    void OnTMTimer()
    {
        ThisApplication.MainFormWrapper.Text = DateTime.now.tostring()..
    }
    --------------------
    And I got a deadlock.
    Because the main UI thread is waiting for event return.
    and Event handler in vsta want to invoke method in UI thread.

    I read the post in previous section, I notice you mentioned it's necessary to new a thread to call macros. Is this I have to do to resolve this question?
    If it is , timer will create and closed thread too ofen I think.
    Any better solution?

    thanks.

  • 09-08-2008 2:01 PM In reply to

    • Gary
    • Top 10 Contributor
    • Joined on 07-13-2006
    • Posts 307

    Re: Some general questions

    Are you seeing this deadlock running the VSTA debugger with a System.Addin.Hosting.AddinProcess, also known as 'Out-Of-Process' or 3rd process debugging?

    Does the same deadlock happen when running the add-in without debugging?

    The .Invoke() called inside MainFormWrapper.Text property should not block and should allow cross-thread updates to UI, so I'm not sure why you are seeing this deadlock. 

     

  • 09-08-2008 7:55 PM In reply to

    Re: Some general questions

    Yes, I followed the help from "Non-Destructive Debugging That Works with a Running Host Application" of MSDN.
    When Invoke() was called, the main UI thread was waiting for the function "OnTMTimerEventHandler(this, ea);"  return. So I think the Invoke() function would be blocked.
    When I run OnTimer in another thread, the deadlock won't happen.

    And I got another question about event argument.
    When I declare the argument in the event handler sub (VB.NET), vsta will be run very very slow.
    If the sub arguments were removed (VB.NET), it will run smoothly.
    If I write addin in CSharp, it will run smoothly with arguments.

    here is my vsta code:
    -----------------------------------
        Private Sub WorkSheet1_Startup(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Startup
            AddHandler WorkSheet.WorkBook.TimeMachine.OnTMTimerEventHandler, AddressOf OnTMTimer
        End Sub

        ' this version will be very slow because we have sub argument
        Private Sub OnTMTimer(ByVal sender As Object, ByVal e As TMTimerEventArgs)
            Try
                Dim tm As String
                tm = WorkSheet.WorkBook.TimeMachine.CurrentTMDateTime.ToString()
                label1.Text = tm
                ReadData()
            Catch ex As Exception

            End Try
        End Sub

        ' this version will be normal if we don't have any argument
        Private Sub OnTMTimer()
            Try
                Dim tm As String
                tm = WorkSheet.WorkBook.TimeMachine.CurrentTMDateTime.ToString()
                label1.Text = tm
                ReadData()
            Catch ex As Exception
            End Try
        End Sub
    ------------------------------------------------------------------
    here is my TMTimerEventArgs in host app
    -------------------------------------------------------
        public class TMTimerEventArgs : EventArgs
        {
            public System.DateTime _dateTime;
            public TMTimerEventArgs(System.DateTime t)
            {
                _dateTime = t;
            }
            public System.DateTime DateTime
            {
                get { return _dateTime; }
            }
        }
    ---------------------------------------------------------

    Why this happened?

    Thanks.

    Yongming
  • 09-09-2008 4:45 AM In reply to

    • Gary
    • Top 10 Contributor
    • Joined on 07-13-2006
    • Posts 307

    Re: Some general questions

    >>When I run OnTimer in another thread, the deadlock won't happen.
    Have you set AllThreadsRunOnFuncEval to 1 to resolve add-in debugger blocking issues?

    The samples with the release version of VSTA 2.0 SDK include this provision:

    // *******************************************************************
    // Run VSTA setup

    if (setupVSTA)
    {
        var vstaCommand = "\"" + vstaExeLocation + "\" /HostID " + hostID + " /setup";

        var vstaExec = wshShell.Exec(vstaCommand);
        while (vstaExec.Status == 0)
        {
            WScript.Sleep(100);
        }
       
        // We need to set AllThreadsRunOnFuncEval to 1 to resolve issues during third-proc debugging.
        // Please see documentation for more information.
        try
        {
            wshShell.RegWrite("HKLM\\Software\\Microsoft\\VSTAHost\\" +
                hostID + "\\9.0\\AD7Metrics\\Engine\\{449EC4CC-30D2-4032-9256-EE18EB41B62B}\\AllThreadsRunOnFuncEval", "1", "REG_DWORD");

        }
        catch(ex)
        {
            WScript.Echo("Warning: fail to write AllThreadsRunOnFuncEval key. " + ex.message);
        }
    }
    ==

    >>When I declare the argument in the event handler sub (VB.NET), vsta will be run very very slow.
    >>If the sub arguments were removed (VB.NET), it will run smoothly.
    >>If I write addin in CSharp, it will run smoothly with arguments.

    Will have to look into this...

  • 09-09-2008 10:54 PM In reply to

    Re: Some general questions

    Yes, I tried to add the entry AllThreadsRunOnFuncEval in registry.
    But don't work.

    the main thread blocked at
    OnTMTimerEventHandler(this, ea);
    -----------------------------------
            void _timemachine_OnTMTimer(object sender, AxTimeMachineLib._DTimeMachineEvents_OnTMTimerEvent e)
            {
                _currentTMDateTime = e.tmCurrentTime;
                try
                {
                    if (OnTMTimerEventHandler != null)
                    {
                        TMTimerEventArgs ea = new TMTimerEventArgs(e.tmCurrentTime);
                        OnTMTimerEventHandler(this, ea);
                    }
                }
                catch (System.Exception ex)
                {
                    OnTMTimerEventHandler = null;
                    System.Diagnostics.Debug.WriteLine(ex.Message);
                }
            }

    ------------------------------------
    the other thread blocked at
    _control.Invoke((SetTextDelegate)delegate(string t) {
    ------------------------------------
            private delegate void SetTextDelegate(string t);
            public string Text
            {
                get { return _control.Text;}
                set {
                    if (_control.InvokeRequired)
                    {
                        _control.Invoke((SetTextDelegate)delegate(string t) {
                            try
                            {
                                _control.Text = t;
                            }
                            catch (System.Exception e)
                            {
                                System.Diagnostics.Debug.WriteLine(e.Message);   
                            }
                        }, value);
                        //_control.Invoke(new SetTextDelegate(SetText), value);
                    }
                    else
                        _control.Text = value;
                }
            }

    the vsta code
    ----------------------------
        Private Sub WorkSheet1_Startup(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Startup
            AddHandler WorkBook.TimeMachine.OnTMTimerEventHandler, AddressOf OnTimer
        End Sub

        Private Sub OnTimer()
            label1.Text = WorkBook.TimeMachine.CurrentTMDateTime.ToString()
        End Sub
    -------------------------------
  • 09-10-2008 9:54 AM In reply to

    Re: Some general questions

    Hi, I got another problem when operate collection.
    at  serias.Points.AddY(dataValues.GetValue(0, j))
    -------------------------------------------------------------------
        Public Sub UpdateChart(ByVal Chart As ProcessX.VSTA.UIWrapper.Chart, ByVal mydata As linkinfo)
            ReadData(dataValues)
            Dim serias As Series
            serias = Chart.Series("S1")
            For j = 0 To dataValues.Length - 1
                serias.Points.AddY(dataValues.GetValue(0, j))
            Next
        End Sub
    -------------------------------
    vsta throw an exception:
    -------------------------------
     A first chance exception of type 'System.Runtime.Serialization.SerializationException' occurred in mscorlib.dll
    can't regist one object twice (It is not excactly the vsta print bacause the language environment, I translate it).
    --------------------------------------

    I try to debug in the host , here is the exception stack:
    ---------------------------------------
         mscorlib.dll!System.Runtime.Serialization.ObjectManager.RegisterObject(object obj, long objectID, System.Runtime.Serialization.SerializationInfo info, long idOfContainingObj, System.Reflection.MemberInfo member, int[] arrayIndex) + 0x385 bytes   
    >    Microsoft.VisualStudio.Tools.Applications.Adapter.v9.0.dll!Microsoft.VisualStudio.Tools.Applications.SerializableObjectContractFormatter.DeserializeArray(System.AddIn.Contract.ISerializableObjectContract deserialize, System.AddIn.Contract.SerializableObjectData data, System.Type typeToReturn, Microsoft.VisualStudio.Tools.Applications.TypeInfrastructureManager typeInfrastructureManager) + 0x291 bytes   
         Microsoft.VisualStudio.Tools.Applications.Adapter.v9.0.dll!Microsoft.VisualStudio.Tools.Applications.SerializableObjectContractFormatter.Deserialize(System.AddIn.Contract.ISerializableObjectContract deserialize, System.Type expectedType, Microsoft.VisualStudio.Tools.Applications.TypeInfrastructureManager typeInfrastructureManager = {Microsoft.VisualStudio.Tools.Applications.TypeInfrastructureManager}) + 0x2ab bytes   
         Microsoft.VisualStudio.Tools.Applications.Adapter.v9.0.dll!Microsoft.VisualStudio.Tools.Applications.TypeServices.DeserializeToObject(System.AddIn.Contract.ISerializableObjectContract contract, System.Type expectedType, Microsoft.VisualStudio.Tools.Applications.TypeInfrastructureManager typeInfrastructureManager) + 0x58 bytes   
         Microsoft.VisualStudio.Tools.Applications.Adapter.v9.0.dll!Microsoft.VisualStudio.Tools.Applications.TypeServices.ObjectFromContract(System.AddIn.Contract.IContract remoteContract, System.Type expectedType, Microsoft.VisualStudio.Tools.Applications.TypeInfrastructureManager typeInfrastructureManager) + 0x29a bytes   
         Microsoft.VisualStudio.Tools.Applications.Adapter.v9.0.dll!Microsoft.VisualStudio.Tools.Applications.TypeServices.ObjectFromRemoteArgument(System.AddIn.Contract.RemoteArgument remoteArg, System.Type expectedType, Microsoft.VisualStudio.Tools.Applications.TypeInfrastructureManager typeInfrastructureManager) + 0xa6 bytes   
         Microsoft.VisualStudio.Tools.Applications.Adapter.v9.0.dll!Microsoft.VisualStudio.Tools.Applications.Internal.AdapterHelpers.PreProcessArguments(System.AddIn.Contract.Collections.IRemoteArgumentArrayContract arguments = {System.Runtime.Remoting.Proxies.__TransparentProxy}, System.Reflection.ParameterInfo[] parameters = {System.Reflection.ParameterInfo[1]}, Microsoft.VisualStudio.Tools.Applications.TypeInfrastructureManager typeInfrastructureManager = {Microsoft.VisualStudio.Tools.Applications.TypeInfrastructureManager}, out Microsoft.VisualStudio.Tools.Applications.Internal.ContractLockData lockData = {Microsoft.VisualStudio.Tools.Applications.Internal.ContractLockData}) + 0xda bytes   
         Microsoft.VisualStudio.Tools.Applications.Adapter.v9.0.dll!Microsoft.VisualStudio.Tools.Applications.RemoteMethodInfoAdapter.System.AddIn.Contract.Automation.IRemoteMethodInfoContract.Invoke(System.AddIn.Contract.Automation.IRemoteObjectContract target, System.Reflection.BindingFlags bindingFlags = Instance | Static | Public | InvokeMethod, System.AddIn.Contract.Collections.IRemoteArgumentArrayContract arguments = {System.Runtime.Remoting.Proxies.__TransparentProxy}, int lcid = 0) + 0x58 bytes   
         [Native to Managed Transition]   
         [Managed to Native Transition]   
         mscorlib.dll!System.Runtime.Remoting.Messaging.StackBuilderSink.PrivateProcessMessage(System.RuntimeMethodHandle md, object[] args, object server, int methodPtr, bool fExecuteInContext, out object[] outArgs) + 0x23 bytes   
         mscorlib.dll!System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(System.Runtime.Remoting.Messaging.IMessage msg, int methodPtr, bool fExecuteInContext) + 0x13b bytes   
         mscorlib.dll!System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(System.Runtime.Remoting.Messaging.IMessage msg) + 0xc bytes   
         mscorlib.dll!System.Runtime.Remoting.Messaging.ServerObjectTerminatorSink.SyncProcessMessage(System.Runtime.Remoting.Messaging.IMessage reqMsg) + 0x55 bytes   
         mscorlib.dll!System.Runtime.Remoting.Lifetime.LeaseSink.SyncProcessMessage(System.Runtime.Remoting.Messaging.IMessage msg) + 0x1e bytes   
         mscorlib.dll!System.Runtime.Remoting.Messaging.ServerContextTerminatorSink.SyncProcessMessage(System.Runtime.Remoting.Messaging.IMessage reqMsg) + 0x71 bytes   
         mscorlib.dll!System.Runtime.Remoting.Channels.CrossContextChannel.SyncProcessMessageCallback(object[] args) + 0x7f bytes   
         mscorlib.dll!System.Runtime.Remoting.Channels.ChannelServices.DispatchMessage(System.Runtime.Remoting.Channels.IServerChannelSinkStack sinkStack, System.Runtime.Remoting.Messaging.IMessage msg = {System.Runtime.Remoting.Messaging.MethodCall}, out System.Runtime.Remoting.Messaging.IMessage replyMsg = null) + 0x22e bytes   
         mscorlib.dll!System.Runtime.Remoting.Channels.DispatchChannelSink.ProcessMessage(System.Runtime.Remoting.Channels.IServerChannelSinkStack sinkStack, System.Runtime.Remoting.Messaging.IMessage requestMsg, System.Runtime.Remoting.Channels.ITransportHeaders requestHeaders, System.IO.Stream requestStream, out System.Runtime.Remoting.Messaging.IMessage responseMsg, out System.Runtime.Remoting.Channels.ITransportHeaders responseHeaders, out System.IO.Stream responseStream) + 0x32 bytes   
         System.Runtime.Remoting.dll!System.Runtime.Remoting.Channels.BinaryServerFormatterSink.ProcessMessage(System.Runtime.Remoting.Channels.IServerChannelSinkStack sinkStack = {System.Runtime.Remoting.Channels.ServerChannelSinkStack}, System.Runtime.Remoting.Messaging.IMessage requestMsg = {System.Runtime.Remoting.Messaging.MethodCall}, System.Runtime.Remoting.Channels.ITransportHeaders requestHeaders, System.IO.Stream requestStream, out System.Runtime.Remoting.Messaging.IMessage responseMsg = null, out System.Runtime.Remoting.Channels.ITransportHeaders responseHeaders = null, out System.IO.Stream responseStream = null) + 0x3bc bytes   
         System.Runtime.Remoting.dll!System.Runtime.Remoting.Channels.Ipc.IpcServerTransportSink.ServiceRequest(object state) + 0x172 bytes   
         System.Runtime.Remoting.dll!System.Runtime.Remoting.Channels.SocketHandler.ProcessRequestNow() + 0x34 bytes   
         System.Runtime.Remoting.dll!System.Runtime.Remoting.Channels.RequestQueue.ProcessNextRequest(System.Runtime.Remoting.Channels.SocketHandler sh) + 0x17 bytes   
         System.Runtime.Remoting.dll!System.Runtime.Remoting.Channels.SocketHandler.BeginReadMessageCallback(System.IAsyncResult ar) + 0xb6 bytes   
         System.Runtime.Remoting.dll!System.Runtime.Remoting.Channels.Ipc.IpcPort.AsyncFSCallback(uint errorCode, uint numBytes, System.Threading.NativeOverlapped* pOverlapped) + 0x50 bytes   
         mscorlib.dll!System.Threading._IOCompletionCallback.PerformIOCompletionCallback(uint errorCode, uint numBytes, System.Threading.NativeOverlapped* pOVERLAP) + 0x54 bytes   
    --------------------------------------------------------------------
    and will print:
    ---------------------------------------------
    A first chance exception of type 'System.Runtime.Serialization.SerializationException' occurred in mscorlib.dll
    A first chance exception of type 'System.Runtime.Serialization.SerializationException' occurred in Microsoft.VisualStudio.Tools.Applications.Adapter.v9.0.dll
    A first chance exception of type 'System.Runtime.Serialization.SerializationException' occurred in Microsoft.VisualStudio.Tools.Applications.Adapter.v9.0.dll  
    ----------------------------------------------

    Could you give me some hints?
    Thanks.

    Yongming


  • 09-10-2008 5:37 PM In reply to

    • Gary
    • Top 10 Contributor
    • Joined on 07-13-2006
    • Posts 307

    Re: Some general questions

    You should look at collections in SDK samples and notice the changes required in proxy to support byvalue structs.  I think that your ByVal Chart may not be connected to a remote Chart object on the application.

    You may need to do something like:

    Application.Chart.Series("S1").Points.AddY(...)

  • 09-10-2008 10:59 PM In reply to

    Re: Some general questions

    Thanks, Gary,
    I write code like following at first,
    Application.Chart.Series("S1").Points.AddY(...).
    It's the same.

    This exception happened occasionally, now always.
    most of the time it run correctly.
    Seems depend on the frequency this function was called.
    The faster the error occured.


  • 09-15-2008 11:53 AM In reply to

    • Melody
    • Top 10 Contributor
    • Joined on 04-26-2007
    • Syracuse, NY
    • Posts 244

    Re: Some general questions

    wangym,

    I'd be happy to look into further if you can send a reproducible sample (with ShapeApp or any way that is convenient to you) to vstasupport@summsoft.com.

    Thanks,

    -Melody

Page 2 of 3 (31 items) < Previous 1 2 3 Next > | RSS
Copyright Summit Software Company, 2008. All rights reserved.