Friday, July 20, 2007

Cross thread operation failure , Use Invoke, BeginInvoke fn...

Cross thread operation failure :

In Visual studio 2005, if we are accessing the control within a form, at run time we will get
Cross thread operation failure.

.NET runtime checks whether the control is used in the thread which created the control. if it is used within the thread at which the control is created, then it will allows execution.
otherwise the .NET runtime will throws an exception.

in the following example if we are creating the thread within that thread if we try to add data to the listbox. .NET runtime will throws exception at
runtime.


For Cross thread operation, we have to call the Invoke() or BeginInvoke() fn to update the control.

Invoke() and BeginInvoke() fns are thread safe. all other threads are not thread safe. the user has to make it as thread safe.

within Thread function, we called the

listBox1.BeginInvoke(m_UpdateList, "sundar");

which inturn updates the listbox. BeginInvoke() or Invoke() blocks the thread until it updates the data to the control.


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


namespace CrossThread
{
public partial class Form1 : Form
{
private Thread thread1 = null;
private ThreadStart threadStart1 = null;

public delegate void UpdateList(string text);
public UpdateList m_UpdateList = null;



public Form1()
{
InitializeComponent();
m_UpdateList += new UpdateList(SetToList1);
threadStart1 = new ThreadStart(AddToList1);
thread1 = new Thread(threadStart1);

}


public void SetToList1(string text)
{
listBox1.Items.Add(text);
}


private void AddToList1()
{
try
{
int i = 10;
while (true)
{
if (i <= 0) break;
listBox1.BeginInvoke(m_UpdateList, "sundar");
i--;
Thread.Sleep(1000);
}

}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());

}
}

private void btnStart_Click(object sender, EventArgs e)
{

try
{
thread1.Start();
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.ToString());
}

}

private void btnStop_Click(object sender, EventArgs e)
{
thread1.Abort();
}
}
}



Use of Invoke() fn >>>

Every control has the following members:

InvokeRequired (boolean field)
Invoke() fn


InvokeRequired field is true if the cross thread operation takes place otherwise it will be false.


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

namespace CrossThreadInvoke
{
public partial class Form1 : Form
{

private Thread thread1 = null;
private ThreadStart threadStart1 = null;
delegate void UpdateControl (string text);
event UpdateControl m_UpdateControl = null;



public Form1()
{
InitializeComponent();
threadStart1 = new ThreadStart(ThreadProcedure);
thread1 = new Thread(threadStart1);
m_UpdateControl = new UpdateControl(UpdateList);

}
private void UpdateList(string text)
{
if (listBox1.InvokeRequired)
{
listBox1.Invoke(m_UpdateControl, text);
}
else
{
listBox1.Items.Add(text);
}
}

private void ThreadProcedure()
{
int i = 0;
while (true)
{
if (i > 10)
{
break;
}

m_UpdateControl("Sundar");
i++;
}
thread1.Abort();
}
private void btnStart_Click(object sender, EventArgs e)
{
thread1.Start();
}

private void btnStop_Click(object sender, EventArgs e)
{
thread1.Abort();
}
}
}

No comments: