title: Multi-threading calls in Windows Forms application?
body: <p>I'm trying to make my C# application multi threaded because sometimes, I get an exception that says I have made a call to a thread in an unsafe manner. I've never done any multi-threading before in a program, so bear with me if I sound kinda ignorant on the issue. </p>
  
  <p>The overview of my program is that I want to make a performance monitoring applicaiton. What this entails is using the process and performance counter class in C# to launch and monitor an application's processor time, and sending that number back to the UI. However, in the method that actually calls the performance counter's nextValue method (which is set to perform every second thanks to a timer), I would sometimes get the aforementioned exception that would talk about calling a thread in an unsafe manner. </p>
  
  <p>I've attached some of the code for your perusal. I know this is kind of a time consuming question, so I'd be really grateful if anyone could offer me any help as to where to make a new thread and how to call it in a safe way. I tried looking at what was up on MSDN, but that just kinda confused me. </p>
  
  <pre><code>private void runBtn_Click(object sender, EventArgs e)
  {
      // this is called when the user tells the program to launch the desired program and
      // monitor it's CPU usage.
  
      // sets up the process and performance counter
      m.runAndMonitorApplication();
  
      // Create a new timer that runs every second, and gets CPU readings.
      crntTimer = new System.Timers.Timer();
      crntTimer.Interval = 1000;
      crntTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
      crntTimer.Enabled = true;
  }
  
  private void OnTimedEvent(object source, ElapsedEventArgs e)
  {
      // get the current processor time reading 
      float cpuReading = m.getCPUValue();
  
      // update the current cpu label
      crntreadingslbl.Text = cpuReading.ToString(); // 
  
  }
  // runs the application 
  public void runAndMonitorApplication()
  {
      p = new Process();
      p.StartInfo.UseShellExecute = true;
      p.StartInfo.CreateNoWindow = true;
      p.StartInfo.FileName = fileName;
      p.Start();
  
      pc = new System.Diagnostics.PerformanceCounter("Process",
                  "% Processor Time",
                  p.ProcessName,
                  true);
  }
  
  // This returns the current percentage of CPU utilization for the process
  public float getCPUValue()
  {
      float usage = pc.NextValue();
  
      return usage;
  }
  </code></pre>