Filling dataset in thread throws an exception

G

Guest

Hello all,

I have a problem with SqlDataAdapter.Fill method called from a thread causing an SEHException to be thrown (which originates deep from unmanaged Windows code). Let me show schematic code:

class MyClass
{
Timer timer ;
MyDataSet ds ;
SqlDataAdapter da ;
DataGrid grid ;

public MyClass()
{
//initialize things
grid.DataSource = ds.MyTable ;
}

private void ThreadMethod()
{
//use SqlCommand to do some inserts
ds.MyTable.Clear() ;
da.Fill( ds.MyTable ) ;
}

private void timer_Tick(object sender, System.EventArgs e)
{
Thread t = new Thread( new ThreadStart( this.ThreadMethod ) ) ;
t.Start() ;
}
}

My program imports data from text files, which are generated by another application, into SQL Server database. For that, it uses a timer to periodically check for new files and import their contents into database. I have a DataAdapter and DataSet with a DataGrid bound to it to generate and visualize some statistics on imported data to the user. This DataSet should be refreshed afer every import. The whole read files/insert into database/refresh statistics code is run in thread, so the application doesn't get unresponsive when timer fires. My problem is that soon after the thread exits, I get this exception:

1c260d16()
USER32.DLL!77e12ca8()
USER32.DLL!77e14764()
USER32.DLL!77e15a40()
NTDLL.DLL!77fa15ef()
USER32.DLL!77e134ff()
system.windows.forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods+IMsoComponentManager.FPushMessageLoop(int dwComponentID = 1, int reason = -1, int pvLoopData = 0) + 0x1c0 bytes
system.windows.forms.dll!ThreadContext.RunMessageLoopInner(int reason = -1, System.Windows.Forms.ApplicationContext context = {System.Windows.Forms.ApplicationContext}) + 0x1f3 bytes
system.windows.forms.dll!ThreadContext.RunMessageLoop(int reason = -1, System.Windows.Forms.ApplicationContext context = {System.Windows.Forms.ApplicationContext}) + 0x50 bytes
system.windows.forms.dll!System.Windows.Forms.Application.Run(System.Windows.Forms.Form mainForm = {MagazynCelny.MainForm}) + 0x34 bytes
MagazynCelny.exe!MagazynCelny.MainForm.Main() Line 1434 C#

If I comment out the "da.Fill( ds.MyTable)" method call in ThreadMethod, the exception is not thrown. I can't believe it to be a bug in .NET Framework, it would be well documented and fixed by now, what am I doing wrong?

rgds
Alex
 
M

Miha Markic [MVP C#]

Hi Alex,

You shouldn't touch UI controls from within non UI thread - that includes
modifying datasources.

--
Miha Markic [MVP C#] - RightHand .NET consulting & software development
miha at rthand com
www.rthand.com

Alex said:
Hello all,

I have a problem with SqlDataAdapter.Fill method called from a thread
causing an SEHException to be thrown (which originates deep from unmanaged
Windows code). Let me show schematic code:
class MyClass
{
Timer timer ;
MyDataSet ds ;
SqlDataAdapter da ;
DataGrid grid ;

public MyClass()
{
//initialize things
grid.DataSource = ds.MyTable ;
}

private void ThreadMethod()
{
//use SqlCommand to do some inserts
ds.MyTable.Clear() ;
da.Fill( ds.MyTable ) ;
}

private void timer_Tick(object sender, System.EventArgs e)
{
Thread t = new Thread( new ThreadStart( this.ThreadMethod ) ) ;
t.Start() ;
}
}

My program imports data from text files, which are generated by another
application, into SQL Server database. For that, it uses a timer to
periodically check for new files and import their contents into database. I
have a DataAdapter and DataSet with a DataGrid bound to it to generate and
visualize some statistics on imported data to the user. This DataSet should
be refreshed afer every import. The whole read files/insert into
database/refresh statistics code is run in thread, so the application
doesn't get unresponsive when timer fires. My problem is that soon after the
thread exits, I get this exception:
1c260d16()
USER32.DLL!77e12ca8()
USER32.DLL!77e14764()
USER32.DLL!77e15a40()
NTDLL.DLL!77fa15ef()
USER32.DLL!77e134ff()
system.windows.forms.dll!System.Windows.Forms.Application.ComponentManager.S
ystem.Windows.Forms.UnsafeNativeMethods+IMsoComponentManager.FPushMessageLoo
p(int dwComponentID = 1, int reason = -1, int pvLoopData = 0) + 0x1c0 bytes
system.windows.forms.dll!ThreadContext.RunMessageLoopInner(int reason
= -1, System.Windows.Forms.ApplicationContext context =
{System.Windows.Forms.ApplicationContext}) + 0x1f3 bytes
system.windows.forms.dll!ThreadContext.RunMessageLoop(int reason = -1,
System.Windows.Forms.ApplicationContext context =
{System.Windows.Forms.ApplicationContext}) + 0x50 bytessystem.windows.forms.dll!System.Windows.Forms.Application.Run(System.Windows
..Forms.Form mainForm = {MagazynCelny.MainForm}) + 0x34 bytes
MagazynCelny.exe!MagazynCelny.MainForm.Main() Line 1434 C#

If I comment out the "da.Fill( ds.MyTable)" method call in ThreadMethod,
the exception is not thrown. I can't believe it to be a bug in .NET
Framework, it would be well documented and fixed by now, what am I doing
wrong?
 
D

DalePres

You could try creating a public method in the form that owns the datagrid
and using Invoke to call the method, or even use Invoke to call the fill
method of the SqlDataAdapter.

There is one more possibility if your thread needs to wait until the Fill is
complete. You can use:

Lock(da)
{
code here to fill da
}

Keep in mind that your thread will wait for the lock until the da becomes
lockable... so if your app is constantly changing da, this would hang the
thread.

Hope this helps,

Dale

Miha Markic said:
Hi Alex,

You shouldn't touch UI controls from within non UI thread - that includes
modifying datasources.

--
Miha Markic [MVP C#] - RightHand .NET consulting & software development
miha at rthand com
www.rthand.com

Alex said:
Hello all,

I have a problem with SqlDataAdapter.Fill method called from a thread
causing an SEHException to be thrown (which originates deep from unmanaged
Windows code). Let me show schematic code:
class MyClass
{
Timer timer ;
MyDataSet ds ;
SqlDataAdapter da ;
DataGrid grid ;

public MyClass()
{
//initialize things
grid.DataSource = ds.MyTable ;
}

private void ThreadMethod()
{
//use SqlCommand to do some inserts
ds.MyTable.Clear() ;
da.Fill( ds.MyTable ) ;
}

private void timer_Tick(object sender, System.EventArgs e)
{
Thread t = new Thread( new ThreadStart( this.ThreadMethod ) ) ;
t.Start() ;
}
}

My program imports data from text files, which are generated by another
application, into SQL Server database. For that, it uses a timer to
periodically check for new files and import their contents into database. I
have a DataAdapter and DataSet with a DataGrid bound to it to generate and
visualize some statistics on imported data to the user. This DataSet should
be refreshed afer every import. The whole read files/insert into
database/refresh statistics code is run in thread, so the application
doesn't get unresponsive when timer fires. My problem is that soon after the
thread exits, I get this exception:
1c260d16()
USER32.DLL!77e12ca8()
USER32.DLL!77e14764()
USER32.DLL!77e15a40()
NTDLL.DLL!77fa15ef()
USER32.DLL!77e134ff()
system.windows.forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods+IMsoComponentManager.FPushMessageLoo
p(int dwComponentID = 1, int reason = -1, int pvLoopData = 0) + 0x1c0 bytes
system.windows.forms.dll!ThreadContext.RunMessageLoopInner(int reason
= -1, System.Windows.Forms.ApplicationContext context =
{System.Windows.Forms.ApplicationContext}) + 0x1f3 bytes
system.windows.forms.dll!ThreadContext.RunMessageLoop(int reason = -1,
System.Windows.Forms.ApplicationContext context =
{System.Windows.Forms.ApplicationContext}) + 0x50 bytessystem.windows.forms.dll!System.Windows.Forms.Application.Run(System.Windows
.Forms.Form mainForm = {MagazynCelny.MainForm}) + 0x34 bytes
MagazynCelny.exe!MagazynCelny.MainForm.Main() Line 1434 C#

If I comment out the "da.Fill( ds.MyTable)" method call in ThreadMethod,
the exception is not thrown. I can't believe it to be a bug in .NET
Framework, it would be well documented and fixed by now, what am I doing
wrong?
rgds
Alex
 
M

Miha Markic [MVP C#]

Hi Dale,

Unfortunatelly this won't solve the problem.
The filling has to be done within UI thread.
One way would be to Fill a dataset in worker thread and then do the Merge
within UI thread (perhaps by using Invoke method).

--
Miha Markic [MVP C#] - RightHand .NET consulting & development
miha at rthand com
www.rthand.com

DalePres said:
You could try creating a public method in the form that owns the datagrid
and using Invoke to call the method, or even use Invoke to call the fill
method of the SqlDataAdapter.

There is one more possibility if your thread needs to wait until the Fill is
complete. You can use:

Lock(da)
{
code here to fill da
}

Keep in mind that your thread will wait for the lock until the da becomes
lockable... so if your app is constantly changing da, this would hang the
thread.

Hope this helps,

Dale

Miha Markic said:
Hi Alex,

You shouldn't touch UI controls from within non UI thread - that includes
modifying datasources.

--
Miha Markic [MVP C#] - RightHand .NET consulting & software development
miha at rthand com
www.rthand.com

Alex said:
Hello all,

I have a problem with SqlDataAdapter.Fill method called from a thread
causing an SEHException to be thrown (which originates deep from unmanaged
Windows code). Let me show schematic code:
class MyClass
{
Timer timer ;
MyDataSet ds ;
SqlDataAdapter da ;
DataGrid grid ;

public MyClass()
{
//initialize things
grid.DataSource = ds.MyTable ;
}

private void ThreadMethod()
{
//use SqlCommand to do some inserts
ds.MyTable.Clear() ;
da.Fill( ds.MyTable ) ;
}

private void timer_Tick(object sender, System.EventArgs e)
{
Thread t = new Thread( new ThreadStart( this.ThreadMethod ) ) ;
t.Start() ;
}
}

My program imports data from text files, which are generated by
another
application, into SQL Server database. For that, it uses a timer to
periodically check for new files and import their contents into
database.
I
have a DataAdapter and DataSet with a DataGrid bound to it to generate and
visualize some statistics on imported data to the user. This DataSet should
be refreshed afer every import. The whole read files/insert into
database/refresh statistics code is run in thread, so the application
doesn't get unresponsive when timer fires. My problem is that soon after the
thread exits, I get this exception:
system.windows.forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods+IMsoComponentManager.FPushMessageLoo
p(int dwComponentID = 1, int reason = -1, int pvLoopData = 0) + 0x1c0 bytes
= -1, System.Windows.Forms.ApplicationContext context =
{System.Windows.Forms.ApplicationContext}) + 0x1f3 bytes
System.Windows.Forms.ApplicationContext context =
{System.Windows.Forms.ApplicationContext}) + 0x50 bytes
system.windows.forms.dll!System.Windows.Forms.Application.Run(System.Windows
.Forms.Form mainForm = {MagazynCelny.MainForm}) + 0x34 bytes ThreadMethod,
the exception is not thrown. I can't believe it to be a bug in .NET
Framework, it would be well documented and fixed by now, what am I doing
wrong?
 
G

Guest

So in this particular case, which control would you call "Invoke" on
The calling form? The target form? The datagrid itself

I get a little confused that every control has an Invoke method
As an example, I have a form with some basic header information in textboxes etc, then a datagrid below that. I'd like the form to load up and be accessible to the user, and the datagrid to populate in the background

At the moment, it seems if I 'invoke' the method that populates the underlying dataset, the whole form freezes up regardless. I've tried datagrid.invoke(me.populate), form.invoke(me.populate), and even previousform.invoke(targetform.populate) with no luck

Thanks!
 

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