Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

Hi, all

My app create threads transfering data and display the status on the datagrid.

Most of time the number of threads are more than 100.

 

But, the exception comes out.. I put all try catch block. but, it is not catched since the exception occurs while painting datagrid i guess.

Exception:

 

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.UnsafeNativeMethods+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



this exception occurs from:

[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..
		}
	}

 

 

Writing message method called by each thread..

private void MsgEach(int idx, string msg)
	{
		Debug.WriteLine("MsgEach:" + idx + ", " + msg);
		try
		{
			deptList.Rows[idx]["Message"] = msg;
		}
		catch
		{
			Debug.WriteLine("MsgEach");
		}
	}



 

 

This problem comes out since DataGrid painting is not thread safe..

Then what should I do?????

After the exception occurs the Application GUI disappears, but the task threads still work..

I think the GUI painting thread (in java AWTThread..) throw exception and die..

 

This problem doesn't occurs every time.. at the same moment..

 

Any idea to solve this problem????

Sun Certified Web component Developer,

Microsoft Certified Solution Developer .NET,

Software Engineer

Posted

Does anyone know about this issue?

Is the datagrid bound to datatable thread safe?

 

Any idea will help..

 

Thank you.

Sun Certified Web component Developer,

Microsoft Certified Solution Developer .NET,

Software Engineer

Posted

I think I found solution.

DataTable is thread safe for Reading, but not for writing.

So it must be syncronized for multi-threaded writing.

 

All writing to DataGrid/DataTable call the following method that syncronizes writing..

Is this right solution?

private void MsgEach(int idx, string colName, object msg)
{
//Debug.WriteLine("MsgEach:" + idx + ", " + msg);
try
{
	//DataTable is Thread safe for Reading! but, Not for WRITING!!
	//To write, it must be synchronized!
	Monitor.Enter(deptList);
	deptList.Rows[idx][colName] = msg;				
	Monitor.Exit(deptList);
}
catch
{
	Debug.WriteLine("MsgEach");
}
}

Sun Certified Web component Developer,

Microsoft Certified Solution Developer .NET,

Software Engineer

Posted

I don't think that's the right solution.

The number of exception occurance decreased but, still the exception comes out..

Sun Certified Web component Developer,

Microsoft Certified Solution Developer .NET,

Software Engineer

Posted
You will find nearly all the GUI elements are not thread safe' date=' they are designed to be updated from the app's primary thread. If you wish to use them in a multi-threaded way you will need to look at using the control's .Invoke method.[/quote']

 

What does 'using the control's .Invoke method.' means?

I don't understand still after looking up.. the method..

Sun Certified Web component Developer,

Microsoft Certified Solution Developer .NET,

Software Engineer

Posted
What does 'using the control's .Invoke method.' means?

I don't understand still after looking up.. the method..

 

Basicly what invoke does is ensure that the method is called on the GUI thread. Whenever you try doing things which effect the user interface (or controls visible or not) you should always do it on the GUI thread or you might run into problems.

 

What you do is first check if the method is called on the GUI thread. If not, you use (Begin)Invoke to get it handled on the GUI thread. Here is an example.

The example code below is called from a 2nd thread I started to handle some calculations. Along the way it has to give some updates so the user knows what is going on. Those screen updates cant be handled directly from the 2nd thread must be done on the GUI thread -> must be invoked.

 

public void SetTitleBarText(string sTitleBarText)
{
 //Called from gui thread?
 if (this.InvokeRequired)
 { //not on gui thread yet, invoke to gui thread
   //create a delegate that calls this same method.
   ProgressTitleUpdate delUpdate = new ProgressTitleUpdate(SetTitleBarText);
   //put the parameters in an object[]
   object objText = (object) sTitleBarText;
   object[] arParams = {objText};
   //do the actual invoke. The framework will call this method again (delUpdate delegate) with parameter from GUI thread.
   BeginInvoke(delUpdate, arParams);
 }
 else
 { //on gui thread -> do gui thing.
   this.Text = sTitleBarText;
 }
}

Nothing is as illusive as 'the last bug'.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...