Index: stable/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleModel.cs
===================================================================
--- stable/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleModel.cs	(revision 15788)
+++ stable/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkEnsembleModel.cs	(revision 16387)
@@ -36,15 +36,6 @@
   public sealed class NeuralNetworkEnsembleModel : ClassificationModel, INeuralNetworkEnsembleModel {
 
+    private object mlpEnsembleLocker = new object();
     private alglib.mlpensemble mlpEnsemble;
-    public alglib.mlpensemble MultiLayerPerceptronEnsemble {
-      get { return mlpEnsemble; }
-      set {
-        if (value != mlpEnsemble) {
-          if (value == null) throw new ArgumentNullException();
-          mlpEnsemble = value;
-          OnChanged(EventArgs.Empty);
-        }
-      }
-    }
 
     public override IEnumerable<string> VariablesUsedForPrediction {
@@ -102,5 +93,8 @@
           x[column] = inputData[row, column];
         }
-        alglib.mlpeprocess(mlpEnsemble, x, ref y);
+        // mlpeprocess writes data in mlpEnsemble and is therefore not thread-safe
+        lock (mlpEnsembleLocker) {
+          alglib.mlpeprocess(mlpEnsemble, x, ref y);
+        }
         yield return y[0];
       }
@@ -119,5 +113,8 @@
           x[column] = inputData[row, column];
         }
-        alglib.mlpeprocess(mlpEnsemble, x, ref y);
+        // mlpeprocess writes data in mlpEnsemble and is therefore not thread-safe
+        lock (mlpEnsembleLocker) {
+          alglib.mlpeprocess(mlpEnsemble, x, ref y);
+        }
         // find class for with the largest probability value
         int maxProbClassIndex = 0;
@@ -139,14 +136,5 @@
       return new NeuralNetworkEnsembleClassificationSolution(this, new ClassificationEnsembleProblemData(problemData));
     }
-
-    #region events
-    public event EventHandler Changed;
-    private void OnChanged(EventArgs e) {
-      var handlers = Changed;
-      if (handlers != null)
-        handlers(this, e);
-    }
-    #endregion
-
+   
     #region persistence
     [Storable]
Index: stable/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkModel.cs
===================================================================
--- stable/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkModel.cs	(revision 15788)
+++ stable/HeuristicLab.Algorithms.DataAnalysis/3.4/NeuralNetwork/NeuralNetworkModel.cs	(revision 16387)
@@ -36,15 +36,6 @@
   public sealed class NeuralNetworkModel : ClassificationModel, INeuralNetworkModel {
 
+    private object mlpLocker = new object();
     private alglib.multilayerperceptron multiLayerPerceptron;
-    public alglib.multilayerperceptron MultiLayerPerceptron {
-      get { return multiLayerPerceptron; }
-      set {
-        if (value != multiLayerPerceptron) {
-          if (value == null) throw new ArgumentNullException();
-          multiLayerPerceptron = value;
-          OnChanged(EventArgs.Empty);
-        }
-      }
-    }
 
     public override IEnumerable<string> VariablesUsedForPrediction {
@@ -106,5 +97,8 @@
           x[column] = inputData[row, column];
         }
-        alglib.mlpprocess(multiLayerPerceptron, x, ref y);
+        // NOTE: mlpprocess changes data in multiLayerPerceptron and is therefore not thread-save!
+        lock (mlpLocker) {
+          alglib.mlpprocess(multiLayerPerceptron, x, ref y);
+        }
         yield return y[0];
       }
@@ -112,5 +106,5 @@
 
     public override IEnumerable<double> GetEstimatedClassValues(IDataset dataset, IEnumerable<int> rows) {
-      double[,] inputData = dataset.ToArray( allowedInputVariables, rows);
+      double[,] inputData = dataset.ToArray(allowedInputVariables, rows);
 
       int n = inputData.GetLength(0);
@@ -123,5 +117,8 @@
           x[column] = inputData[row, column];
         }
-        alglib.mlpprocess(multiLayerPerceptron, x, ref y);
+        // NOTE: mlpprocess changes data in multiLayerPerceptron and is therefore not thread-save!
+        lock (mlpLocker) {
+          alglib.mlpprocess(multiLayerPerceptron, x, ref y);
+        }
         // find class for with the largest probability value
         int maxProbClassIndex = 0;
@@ -144,13 +141,4 @@
     }
 
-    #region events
-    public event EventHandler Changed;
-    private void OnChanged(EventArgs e) {
-      var handlers = Changed;
-      if (handlers != null)
-        handlers(this, e);
-    }
-    #endregion
-
     #region persistence
     [Storable]
