Painting Control issue by Muti-Thread!!

G

GoodMorningSky

Hi, all
This is common problem when muti thread update an control.


My app create threads that each thread transfers data from different server
and display the status on the datagrid bound to DataTable obj.
Most of time the number of threads are more than 100.
Which means more than one hundred threads update the DataTable and DataGrid
shows the result. Also, 3 labels are accessed by the threads to show number
of threads: Total, Success, Fail.

But, problem is that the NullReferenceException comes out.. I put all try
catch block. but, it is not catched since the exception occurs while
painting datagrid i guess. The window painting thread (AWTThread in Java I
guess) throws it.
When it happends window GUI disappears but, other threads still works.
Process is killed when all threads die.

Exception is catched..at
[STAThread]
static void Main()
{
try
{
if (SkyComponents.SkyWinUtils.PrevInstance())
{
MessageBox.Show ("Program is already running!");
return;
}
Application.Run(new frmMDIMain());
}
catch(Exception ex)
{
Debug.WriteLine("********** Dead Thread: " + Thread.CurrentThread.Name);
Debug.WriteLine(ex.StackTrace);
Debug.WriteLine(ex.Message); //here..
}
}


the ex.Message is

Exception: from output window

MsgEach:170, PayrollReport: 327/725
********** Dead Thread:
MsgEach:165, PayrollReport: 511/780
MsgEach:166, PayrollReport: 512/672
MsgEach:165, PayrollReport: 512/780
MsgEach:166, PayrollReport: 513/672
MsgEach:170, PayrollReport: 328/725
at System.Data.DataColumnPropertyDescriptor.GetValue(Object component)
at
System.Windows.Forms.DataGridColumnStyle.GetColumnValueAtRow(CurrencyManager
source, Int32 rowNum)
at System.Windows.Forms.DataGridTextBoxColumn.Paint(Graphics g, Rectangle
bounds, CurrencyManager source, Int32 rowNum, Brush backBrush, Brush
foreBrush, Boolean alignToRight)
at
System.Windows.Forms.DataGridRelationshipRow.PaintCellContents(Graphics g,
Rectangle cellBounds, DataGridColumnStyle column, Brush backBr, Brush
foreBrush, Boolean alignToRight)
at System.Windows.Forms.DataGridRow.PaintData(Graphics g, Rectangle
bounds, Int32 firstVisibleColumn, Int32 columnCount, Boolean alignToRight)
at System.Windows.Forms.DataGridRelationshipRow.Paint(Graphics g,
Rectangle bounds, Rectangle trueRowBounds, Int32 firstVisibleColumn, Int32
numVisibleColumns, Boolean alignToRight)
at System.Windows.Forms.DataGrid.PaintRows(Graphics g, Rectangle&
boundingRect)
at System.Windows.Forms.DataGrid.PaintGrid(Graphics g, Rectangle
gridBounds)
at System.Windows.Forms.DataGrid.OnPaint(PaintEventArgs pe)
at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e,
Int16 layer, Boolean disposeEventArgs)
at System.Windows.Forms.Control.WmPaint(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd,
Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at
System.Windows.Forms.ComponentManager.System.Windows.Forms.UnsafeNativeMetho
ds+IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason,
Int32 pvLoopData)
at System.Windows.Forms.ThreadContext.RunMessageLoopInner(Int32 reason,
ApplicationContext context)
at System.Windows.Forms.ThreadContext.RunMessageLoop(Int32 reason,
ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at TimeClockAdmin.frmMDIMain.Main() in c:\projects\new time clock
release\new time clock hq\timeclockadmin\frmmdimain.cs:line 497
MsgEach:165, PayrollReport: 513/780
Object reference not set to an instance of an object.
MsgEach:166, PayrollReport: 514/672
MsgEach:170, PayrollReport: 329/725



Method called by each thread to show message.

private void MsgEach(int idx, string msg)
{
Debug.WriteLine("MsgEach:" + idx + ", " + msg);
try
{
// I tried here Monitor.Enter(this|deptList|dataGridObj) with the
all 3 obj.
deptList.Rows[idx]["Message"] = msg;
//Monitor.Exit(..)
}
catch
{
Debug.WriteLine("MsgEach");
}
}


also I tired following obj to synchronizing..

the MsgEach is called by each thread.
public class WriteMsg
{
private DataGrid dg;
private DataTable dt;
public WriteMsg(DataGrid _dg, DataTable _dt)
{
dg = _dg;
dt = _dt;
}
public void MsgEach(int idx, string colName, object msg)
{
//Debug.WriteLine("MsgEach:" + idx + ", " + msg);
try
{
Monitor.Enter(this);
dt.Rows[idx][colName] = msg;

//Application.DoEvents();
Monitor.Exit(this);
}
catch
{
Debug.WriteLine("MsgEach");
}
}
}

But, I got still the exception.

What is the standard or common or whatever..way to solve this
problem...?????
Please, give any comment...
Any comment will help!!!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top