title: C# Backgroundworker and Twincat, How to fire Notification event inside worker thread
body: <p>I had little knowledge about mixing events and threads. The scenario is that there is a C# program running on a PC and Twincat running on a PLC. We need to access PLC variables inside the C# program ( Already done without a background worker thread and its working fine.) , Now we need to move these processing to a thread ( preferably Background Worker ). Here is the code which is not working.( The form contains a START button , which will start BGworker, a STOP button which will cancel BGWorker, and an UPDATE button which will update the values from PLC to a textbox.), But now tcClient_OnNotification is not getting called! Please point out where i am missing, any help will be most appreciated.</p>
  
  <pre><code>    using System;
      using System.Collections.Generic;
      using System.ComponentModel;
      using System.Data;
      using System.Drawing;
      using System.Linq;
      using System.Text;
      using System.Windows.Forms;
  
  
      using System.Threading;         // not added by default
      using System.IO;                // not added by default
      using TwinCAT.Ads;              // not added by default
  
      namespace BGworker
      {
          public partial class Form1 : Form
          {
              private BackgroundWorker bw = new BackgroundWorker();
              private TcAdsClient tcClient;   // C# program is the client.
              private AdsStream dataStream;   // Data transfered through System IOStream
              private BinaryReader binReader; // We are now reading value from PLC
              private int Hintval;            // Handle for integer value
  
              public static bool looping = true;
              public static string receivedtext = "";
  
              public Form1()
              {
                  InitializeComponent();
  
                  bw.WorkerReportsProgress = true;
                  bw.WorkerSupportsCancellation = true;
                  bw.DoWork += new DoWorkEventHandler(bw_DoWork);
                  bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
                  bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
              }
  
              private void Form1_Load(object sender, EventArgs e)
              {
  
              }
  
  
              private void Startbutton_Click(object sender, EventArgs e)
              {
                  if (bw.IsBusy != true)
                  {
                      bw.RunWorkerAsync();
                  }
  
              }
  
  
  
  
              private void Stopbutton_Click(object sender, EventArgs e)
              {
                  if (bw.WorkerSupportsCancellation == true)
                  {
                      bw.CancelAsync();
                  }
              }
  
  
              public void bw_DoWork(object sender, DoWorkEventArgs e)
              {
                  BackgroundWorker worker = sender as BackgroundWorker;
                  dataStream = new AdsStream(1 * 2); // Single value will be read
                  binReader = new BinaryReader(dataStream, Encoding.ASCII);
                  tcClient = new TcAdsClient();
                  tcClient.Connect(801);
                  //Hintval = tcClient.CreateVariableHandle(".GOUTINT");
                  Hintval = tcClient.AddDeviceNotification(".GOUTINT", dataStream, 0, 2, AdsTransMode.OnChange, 100, 0, null);
                  tcClient.AdsNotification += new AdsNotificationEventHandler(tcClient_OnNotification);
  
                  while (true)
                  {
                      if ((worker.CancellationPending == true))
                      {
                          e.Cancel = true;
                          break;
                      }
                      else
                      {
                          System.Threading.Thread.Sleep(100);
                          //worker.ReportProgress((5* 10));
  
                      }
                  }
  
                  tcClient.Dispose();
              }
  
  
              public void tcClient_OnNotification(object sender, AdsNotificationEventArgs e)
              {
                  try
                  {
                      // Setting the position of e.DataStream to the position of the current required value
                      e.DataStream.Position = e.Offset;
  
                      // Determining which variable has changed
                      if (e.NotificationHandle == Hintval)
                      {
                          receivedtext = binReader.ReadInt16().ToString();
                      }
                  }
                  catch (Exception ex)
                  {
                      MessageBox.Show(ex.Message);
                  }
              }
  
              private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
              {
                  if ((e.Cancelled == true))
                  {
                      this.tbProgress.Text = "Canceled!";
                  }
  
                  else if (!(e.Error == null))
                  {
                      this.tbProgress.Text = ("Error: " + e.Error.Message);
                  }
  
                  else
                  {
                      this.tbProgress.Text = "Done!";
                  }
              }
              private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
              {
                  this.tbProgress.Text = (e.ProgressPercentage.ToString() + "%");
              }
  
              private void buttonUpdate_Click(object sender, EventArgs e)
              {
                  this.tbProgress.Text = receivedtext;
              }
  
          }
      }
  </code></pre>
  
  <p>thanks in advance.
  Abhilash.</p>