Quantcast
Channel: R.NET
Viewing all articles
Browse latest Browse all 1634

New Post: Call R script in UI thread crash the app

$
0
0
I am building an application which display a data table and allow user to define computed fields which the help of R functions. E.g., calculate the squreroot of one numeric field, and display the data table and the computed fields. However, it only works on the initial view, and crash when scroll or update the view. Below is a snippet (I am use WCF but it happen with WinForm).
XAML:
<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApplication1"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525" Closing="Window_Closing"
      >
  <Grid>
    <DataGrid x:Name="dataGrid"  HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ScrollViewer.VerticalScrollBarVisibility="Visible" PreviewKeyDown="dataGrid_PreviewKeyDown" />

  </Grid>
</Window>
And the code
using RDotNet;
using RDotNet.Devices;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;

namespace WpfApplication1
{
  /// <summary>
  /// Interaction logic for MainWindow.xaml
  /// </summary>
  public partial class MainWindow : Window
  {
    public static REngine engine;
    public class RValue
    {
      private int value;
     
      public RValue(int value)
      {
        this.value = value;
       }
      public int OriginValue
      {
        get { return value; }
      }

      public double SqrtValue
      {
        get
        {
          string script = "value<-" + value + ";" + "sqrt(value);";
          double rvalue = 0;
            rvalue = MainWindow.engine.Evaluate(script).AsNumeric().First();
          return rvalue;
        }
      }
    }
    public MainWindow()
    {
      InitializeComponent();
      REngine.SetEnvironmentVariables();
      engine = REngine.GetInstance();
      
      engine.Initialize();
     
      List<RValue> values = new List<RValue>(300);
      for (int i = 0; i < 300; i++)
      {
        values.Add(new RValue(i));
      }
      this.dataGrid.ItemsSource = values;
    }

    private void dataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {

    }
    ScrollViewer _scrollViewer = null;
    private void dataGrid_PreviewKeyDown(object sender, KeyEventArgs e)
    {
      if (_scrollViewer == null)
      {
        _scrollViewer = GetVisualChild<ScrollViewer>(this.dataGrid);
      }
      switch (e.Key)
      {
        case Key.PageUp:
          _scrollViewer.PageUp();
          e.Handled = true;
          break;
        case Key.PageDown:
          _scrollViewer.PageDown();
          e.Handled = true;
          break;
      }

    }
    static T GetVisualChild<T>(Visual parent) where T : Visual
    {
      T child = default(T);
      int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
      for (int i = 0; i < numVisuals; i++)
      {
        Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
        child = v as T;
        if (child == null)
        {
          child = GetVisualChild<T>(v);
        }
        if (child != null)
        {
          break;
        }
      }
      return child;
    }
  }
}
The exception is "An exception of type 'System.InvalidOperationException' occurred in WindowsBase.dll and wasn't handled before a managed/native boundary

Additional information: Dispatcher processing has been suspended, but messages are still being processed."
 get
        {
          string script = "value<-" + value + ";" + "sqrt(value);";
          double rvalue = 0;
          var op = Dispatcher.CurrentDispatcher.BeginInvoke(new Action(() => rvalue = MainWindow.engine.Evaluate(script).AsNumeric().First()));
          if (op.Status !=  DispatcherOperationStatus.Completed)
          {
            op.Wait(new TimeSpan(100));
          }
           
          return rvalue;
        }
But it still crash on op.Wait. Have anyone used R.net with WPF or WinForm?

Viewing all articles
Browse latest Browse all 1634

Trending Articles