Multiple forms and threads

  • Thread starter Thread starter Christian Westerlund
  • Start date Start date
C

Christian Westerlund

My problem is the following

I get an ArgumentOutOfRangeException when I navigate up and down on my
datagrid. I hold down the right button which moves to the next cell and
then go up with the left key and repeat that until I get an exception
which usually takes less than a half minute. I have a thread which
updates every 3 second and sends an event every 10th second.
The exception doesn't say anything about what's wrong, I just shows me
the following line:

static void Main()
{
Application.Run(new Frm());
}

I have no idea what's wrong.


Description of my system:

On my main form I have a datagrid with information thats being updated
from a thread. The datagrid is connected to an arraylist like this:

m_datagrid.DataSource = m_updatethread.CollectionInformation;
Binder bnd = Binder.BindToDataGrid(m_datagrid, 0, "{0}");
bnd = Binder.BindToDataGrid(m_datagrid, 1, "{0}");
m_datagrid.Update();

This is my updatingthreads main loop:

while( !this.m_closeRequested ){
getNewData(); // updating information in CollectionInformation
SendEvent();
Sleep( ms );
}


When the sendEvent is called my
MainForm is notified and does the following:

if( this.Visible == true )
{

if( m_datagrid != null && m_updatethread != null)
{
m_datagrid.DataSource = m_updatethread.CollectionInformation;
m_datagrid.Refresh();
}
}
 
This is the information I get :

An unhandled exception of type 'System.ArgumentOutOfRangeException'
occurred in mscorlib.dll

Additional information: ArgumentOutOfRangeException

If I then break and after that continue I get this one:

An unhandled exception of type 'System.ArgumentOutOfRangeException'
occurred in System.Windows.Forms.dll

Additional information: ArgumentOutOfRangeException

If I break and continue on more time the application closes.

/Christian
 
So is the event changing the UI? If so that's the problem. An event
handler is in the context of the calling thread, and you cannot affect UI
elements safely from a thread context other than the primary thread. You
need to use Control.Invoke to update the UI.

-Chris
 
Ok!
So this code is done in the context of the calling thread?

if( this.Visible == true )
{

if( m_datagrid != null && m_updatethread != null)
{
m_datagrid.DataSource = m_updatethread.CollectionInformation;
m_datagrid.Refresh();
}
}

So if I understand this right what I should do to make the UI update is
the following:

if( this.Visible == true )
{

if( m_datagrid != null && m_updatethread != null)
{
m_datagrid.Invoke( new EventHandler( UpdateDataGrid ) );
}
}

private void UpdateDataGrid(object sender, EventArgs e){
m_datagrid.DataSource = m_updatethread.CollectionInformation;
m_datagrid.Refresh();
}


I will test it, please let me know if I misunderstod.

/Christian
 
If the event is raised from a thread, then the handler is in the context of
that thread. yes.

-Chris
 
I have made all the changes to use the Invoke-method and
I also surround all my data access with myMutex.WaitOne() and
myMutex.Release...
But the problem remains. I think that when I move around in the datagrid
the values are re-read when a cell becomes selected and when that does
happen and the other thread updates something in the datastructure an
exception is thrown.

What do you think about my theory?
If I'm right, what can I do to change my program?

/Christian
 
I used the Clone() method and I haven't got any exceptions yet.
Then I enabled another event that is sent to another form which is
created by the mainform. My thread is sending to events now, to two
forms. When I started the program and started my scrolltest the program
freezed but no exception was thrown. When I break the program I see that
I have two threads which is right,

one in the mainForms eventhandler for scrollevent (I'm constantly
scrolling the datagrid on the mainform) It stops at the "if"
if( m_datagrid.CurrentCell.RowNumber > -1)
m_datagrid.Select( m_datagrid.CurrentCell.RowNumber );

the other is my dataupdating and eventsending thread which is stuck, it
has just send an event to my second form and is therefore in the code
for that form trying to Invoke a method which will update the UI on that
form.

Every time it stops att the same places for both threads.

Now, these two threads are both in methods which I have enclosed with mutex.
the mutex object is a member in the eventthread, the forms have a
reference to the eventthread from which they can access the mutex.

How is this possible?

/Christian
 
Back
Top