Wrox Programmer Forums
Go Back   Wrox Programmer Forums > C# and C > C# 1.0 > C#
| Search | Today's Posts | Mark Forums Read
C# Programming questions specific to the Microsoft C# language. See also the forum Beginning Visual C# to discuss that specific Wrox book and code.
Welcome to the p2p.wrox.com Forums.

You are currently viewing the C# section of the Wrox Programmer to Programmer discussions. This is a community of software programmers and website developers including Wrox book authors and readers. New member registration was closed in 2019. New posts were shut off and the site was archived into this static format as of October 1, 2020. If you require technical support for a Wrox book please contact http://hub.wiley.com
  #1 (permalink)  
Old December 13th, 2006, 09:17 AM
Registered User
 
Join Date: Dec 2006
Location: Paris, , France.
Posts: 1
Thanks: 0
Thanked 0 Times in 0 Posts
Send a message via MSN to Richw71
Default Cross-thread operation not valid

Hi,

I have a form that, on clicking a button, kicks off a thread. That thread raises occasional events that I want the original form to trap and show information about.

Everything seems perfectly logical to me, but at run-time I get an error: Cross-thread operation not valid.

The solutions that I have seen work for the case where the code to update the form is contained within the thread itself. In my case, though, I want the thread class to be reusable without modification and so do not want to code references to a particular form inside the thread.

Here is the code, in the form, that uses the thread:


Code:
// This is my UI class: the standard VS2005 created "Form1"
// The form contains a button: button1, and a label: label1

/*  Info:
 *  When the button1 is clicked a thread is created that 
 *  performs a long calculation.   From time-to-time during 
 *  the calculation an event - ChangedResult - is raised and 
 *  this event passes back the current result to the calling 
 *  form for display in label1
*/ 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace TestCrossThreadApp1
{
    public partial class Form1 : Form
    {

        // Default constructor... no surprises
        public Form1()
        {
            InitializeComponent();
        }//Form1

        // The button click event that creates an instance of a "calc" thread
        // an event handling method, onChangedResult, is setup to received
        // the ChangedResult event from the Calc1 thread.
        private void button1_Click(object sender, EventArgs e)
        {
            MyCalcThread Calc1 = new MyCalcThread();
            Calc1.ChangedResult += onChangedResult;
            Calc1.StartCalculation();
        }// button1_click

        // The onChangedResult method is called by delegation
        private void onChangedResult(object sender, CalcEventArgs CEA)
        {
            string s = Convert.ToString(CEA.Result);
            label1.Text = s;  //<-------- This is where the ERROR occurs!
        }// onChangedResult

    }// class Form1

}// Namespace

The following is the code for the thread object and it's eventargs object:

Code:
using System;
using System.Threading;

namespace TestCrossThreadApp1
{
    // Define the delegate for the ChangedResult event
    public delegate void ChangedResultHandler(object sender, CalcEventArgs CEA);

    // Event Arguments
    public class CalcEventArgs : EventArgs
    {
        private int result;

        // Constructor
        public CalcEventArgs(int Result)
        {
            this.result = Result;
        } // Constructor

        // Get Parameter
        public int Result
        {
            get
            {
                return result;
            } // Get
        } // Get Parameter
    }//class CalcEventArgs


    // Declare a class that encapsulates the threaded calculations
    public class MyCalcThread
    {
        // Define an event that will be fired when the calculation result is changed significantly
        public event ChangedResultHandler ChangedResult;

        // This method creates an instance of the event args and raises the ChangedResult event
        public void RaiseResultChangedEvent(int Result)
        {
            CalcEventArgs CEA = new CalcEventArgs(Result);
            ChangedResult(this, CEA);
        }// RaiseResultChangedEvent


        // Public class that starts the calculation in it's own thread
        public void StartCalculation()
        {
            Thread CalculationThread = new Thread(new ThreadStart(CalcThread));
            CalculationThread.Start();
        }// StartCalculation

        // This is a mundane "calculation"
        public void CalcThread()
        {
            int i = 0;

            while (++i < 10000000)
            {
                // Raise the ChangedEvent method via the RaiseResultChangedEvent wrapper
                switch (i)
                {
                    case 1:
                    case 100000:
                    case 500000:
                    case 1000000:
                        RaiseResultChangedEvent(i);
                        break;
                } // switch
            }// While
        }// CalcThread

    }// Class MyCalcThread

}// Namespace

This is very frustrating, so any help that you could offer would be appreciated!

- Rich



Similar Threads
Thread Thread Starter Forum Replies Last Post
cross thread exception YoungLuke C# 1 March 23rd, 2008 06:46 PM
cross thread exception with windows live API YoungLuke C# 2008 aka C# 3.0 1 March 23rd, 2008 01:43 PM
Thread Pool bhavana General .NET 0 October 23rd, 2007 06:15 AM
Which Thread to use and How peace2007 ASP.NET 1.0 and 1.1 Professional 0 September 23rd, 2007 03:24 AM
cross thread Error angelboy C# 2005 1 July 28th, 2007 04:35 AM





Powered by vBulletin®
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Copyright (c) 2020 John Wiley & Sons, Inc.