Calling R.NET from another thread

Sep 23, 2013 at 6:35 AM
Edited Sep 23, 2013 at 6:49 AM
I have a main app where a user can create as many child windows as he likes and each child window can have access to the R Engine. The R Engine is a singleton.

Randomly, usually, if the child windows are created right after the start of the app, the link between the R.NET engine and the child windows doesn't work with the error "Error in application"

What should I do to prevent it from happening?

exception {"Error in the application."} System.Exception {RDotNet.ParseException}
    StackTrace  "   at RDotNet.REngine.Parse(String statement, StringBuilder incompleteStatement)\r\n   at RDotNet.REngine.<Defer>c__Iterator4.MoveNext()\r\n   at System.Linq.Enumerable.LastOrDefault[TSource](IEnumerable`1 source)\r\n   at RDotNet.REngine.Evaluate(String statement)\r\n   
Sep 23, 2013 at 8:38 AM
It certainly does have something to do with COM and multi-threading as the originating thread creating the new thread with window runs R.NET without problems, only the new thread sometimes fail.

Are there any special attributes or patterns I should use?
Developer
Sep 23, 2013 at 9:05 AM
R is single threaded. AS you notice You really should not have multiple threads, forms or otherwise, directly accessing it in parallel. I am afraid this is something largely out of our control. The only thing I can think of is if you had a thread-safe layer on the main thread as the REngine that deals with the concurrent requests from other threads. Lots of difficult work I would guess.
Sep 23, 2013 at 9:51 AM
Thank you.

I think the problem may be with COM marshalling, STA Thread etc.

Can you recommend a way how to create a new window safely?

My code is this:

[STAThread]
    public static void ShowRConsole()
    {
        var rAccess = new RAccess();

        if (!rAccess.CheckRWorks())
        {
            MessageBox.Show("R is not available!", ProductInformation.CompleteProductInformation, MessageBoxButton.OK, MessageBoxImage.Error);
            return;
        }

        var thread = new Thread(() =>
            {
                SynchronizationContext.SetSynchronizationContext(new DispatcherSynchronizationContext(Dispatcher.CurrentDispatcher));

                var window = new RConsole();

                System.Windows.Forms.Integration.ElementHost.EnableModelessKeyboardInterop(window);
                window.Show();

                window.Closed += (s, e) => Dispatcher.CurrentDispatcher.BeginInvokeShutdown(DispatcherPriority.Background);

                window.Show();

                Dispatcher.Run();
            });

        thread.SetApartmentState(ApartmentState.STA);
        thread.Start();
    }
Sep 23, 2013 at 9:52 AM
In detail. the rAccess.CheckRWorks works just fine, but the new thread is failing, though the access to the rEngine is via singleton with all locking.
Sep 24, 2013 at 3:17 AM
Hi:

I dropped this idea as it was not worth pursuing as it turned out to be too unstable.

thanks for your kind help and all my best!