PC Review


Reply
Thread Tools Rate Thread

Breaking change in .NET 1.1 SP1 DataTable - Repro provided

 
 
Urs Eichmann
Guest
Posts: n/a
 
      10th Sep 2004
The following piece of code will run fine in .NET 1.1 without SP1, but
will throw a NullReferenceException in SP1. Sadly, our app no longer
runs with SP1, since it uses the same pattern (changing another row of
data inside a ListChanged event of a DataView).

Could please someone from Microsoft confirm this as a bug, and/or
provide a workaround?

Regards,
Urs


run the following as a console app:

[VB.NET]

Imports System.Data

Module Module1

Private dt As DataTable
Private b As Boolean

Sub Main()

dt = New System.Data.DataTable
dt.Columns.Add("Col1", GetType(String))
dt.Columns.Add("Col2", GetType(String))

Dim dv As New DataView(dt, "", "Col1",
DataViewRowState.CurrentRows)
AddHandler dv.ListChanged, AddressOf OnListchanged
Dim dv2 As New DataView(dt, "", "Col2",
DataViewRowState.CurrentRows)
AddHandler dv2.ListChanged, AddressOf OnListchanged

dt.Rows.Add(New Object() {"a", "b"}) ' NullRefException will be
thrown here

End Sub

Private Sub OnListchanged(ByVal s As Object, ByVal e As
System.ComponentModel.ListChangedEventArgs)

If b Then Return
b = True ' don't want recursive calling

dt.Rows.Add(New Object() {"c", "d"})

End Sub

End Module
 
Reply With Quote
 
 
 
 
Angel Saenz-Badillos[MS]
Guest
Posts: n/a
 
      10th Sep 2004
Urs,
Thanks for posting this, the DataTable is not really my area but I have
forwarded your post and I will let you know as soon as I get any info.

--
Angel Saenz-Badillos [MS] Managed Providers
This posting is provided "AS IS", with no warranties, and confers no
rights.Please do not send email directly to this alias.
This alias is for newsgroup purposes only.
I am now blogging about ADO.NET: http://weblogs.asp.net/angelsb/




"Urs Eichmann" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> The following piece of code will run fine in .NET 1.1 without SP1, but
> will throw a NullReferenceException in SP1. Sadly, our app no longer
> runs with SP1, since it uses the same pattern (changing another row of
> data inside a ListChanged event of a DataView).
>
> Could please someone from Microsoft confirm this as a bug, and/or
> provide a workaround?
>
> Regards,
> Urs
>
>
> run the following as a console app:
>
> [VB.NET]
>
> Imports System.Data
>
> Module Module1
>
> Private dt As DataTable
> Private b As Boolean
>
> Sub Main()
>
> dt = New System.Data.DataTable
> dt.Columns.Add("Col1", GetType(String))
> dt.Columns.Add("Col2", GetType(String))
>
> Dim dv As New DataView(dt, "", "Col1",
> DataViewRowState.CurrentRows)
> AddHandler dv.ListChanged, AddressOf OnListchanged
> Dim dv2 As New DataView(dt, "", "Col2",
> DataViewRowState.CurrentRows)
> AddHandler dv2.ListChanged, AddressOf OnListchanged
>
> dt.Rows.Add(New Object() {"a", "b"}) ' NullRefException will be
> thrown here
>
> End Sub
>
> Private Sub OnListchanged(ByVal s As Object, ByVal e As
> System.ComponentModel.ListChangedEventArgs)
>
> If b Then Return
> b = True ' don't want recursive calling
>
> dt.Rows.Add(New Object() {"c", "d"})
>
> End Sub
>
> End Module



 
Reply With Quote
 
Angel Saenz-Badillos[MS]
Guest
Posts: n/a
 
      13th Sep 2004
Uris,
This is the response that I got from the dataset team:
"This is an unsupported scenario. Any "write" operations on DataSet in an
event handler will result in an unpredictable behavior.
I'd suggest an alternative way of solving his scenario."

I am not sure of what they mean with alternative solution, but it is true
that "touching" the datatable in multiple threads is not supported. You can
probably get arround this limitation by binding on the UI thread before
calling the Add method with something like this (please excuse the code
hack, I am doing copy paste from a c# project I had laying arround,
hopefully you can get the idea of what to look for from here). The basic
concept is that you can only call datatable add on the same thread in which
you created the datatable, in this case we assume you created it on the main
thread.


delegate void UICallback( object param );

void ReBindOnUIThread( object param )
{
//This method will run in the main thread, we can touch the DataTable
here:
dt.Rows.Add(New Object() {"c", "d"})
}

Private Sub OnListchanged(ByVal s As Object, ByVal e As
System.ComponentModel.ListChangedEventArgs)

If b Then Return
b = True ' don't want recursive calling
//you can't touch the datatable here since we are in a different
thread
//dt.Rows.Add(New Object() {"c", "d"})
//instead we rebind on the ui thread using the delegate
this.Invoke( new UICallback( ReBindOnUIThread ), new object[] {
<myobject>} );

End Sub

--
Angel Saenz-Badillos [MS] Managed Providers
This posting is provided "AS IS", with no warranties, and confers no
rights.Please do not send email directly to this alias.
This alias is for newsgroup purposes only.
I am now blogging about ADO.NET: http://weblogs.asp.net/angelsb/


>
> "Urs Eichmann" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
> > The following piece of code will run fine in .NET 1.1 without SP1, but
> > will throw a NullReferenceException in SP1. Sadly, our app no longer
> > runs with SP1, since it uses the same pattern (changing another row of
> > data inside a ListChanged event of a DataView).
> >
> > Could please someone from Microsoft confirm this as a bug, and/or
> > provide a workaround?
> >
> > Regards,
> > Urs
> >
> >
> > run the following as a console app:
> >
> > [VB.NET]
> >
> > Imports System.Data
> >
> > Module Module1
> >
> > Private dt As DataTable
> > Private b As Boolean
> >
> > Sub Main()
> >
> > dt = New System.Data.DataTable
> > dt.Columns.Add("Col1", GetType(String))
> > dt.Columns.Add("Col2", GetType(String))
> >
> > Dim dv As New DataView(dt, "", "Col1",
> > DataViewRowState.CurrentRows)
> > AddHandler dv.ListChanged, AddressOf OnListchanged
> > Dim dv2 As New DataView(dt, "", "Col2",
> > DataViewRowState.CurrentRows)
> > AddHandler dv2.ListChanged, AddressOf OnListchanged
> >
> > dt.Rows.Add(New Object() {"a", "b"}) ' NullRefException will be
> > thrown here
> >
> > End Sub
> >
> > Private Sub OnListchanged(ByVal s As Object, ByVal e As
> > System.ComponentModel.ListChangedEventArgs)
> >
> > If b Then Return
> > b = True ' don't want recursive calling
> >
> > dt.Rows.Add(New Object() {"c", "d"})
> >
> > End Sub
> >
> > End Module

>
>



 
Reply With Quote
 
=?Utf-8?B?TWF5bw==?=
Guest
Posts: n/a
 
      14th Sep 2004
With the installation of SP1 also an app of mine started to work badly for
other reasons: if you are interested in the thread look:
http://msdn.microsoft.com/communitie...xp=&sloc=en-us

If you have any suggestion...

"Angel Saenz-Badillos[MS]" wrote:

> Uris,
> This is the response that I got from the dataset team:
> "This is an unsupported scenario. Any "write" operations on DataSet in an
> event handler will result in an unpredictable behavior.
> I'd suggest an alternative way of solving his scenario."
>
> I am not sure of what they mean with alternative solution, but it is true
> that "touching" the datatable in multiple threads is not supported. You can
> probably get arround this limitation by binding on the UI thread before
> calling the Add method with something like this (please excuse the code
> hack, I am doing copy paste from a c# project I had laying arround,
> hopefully you can get the idea of what to look for from here). The basic
> concept is that you can only call datatable add on the same thread in which
> you created the datatable, in this case we assume you created it on the main
> thread.
>
>
> delegate void UICallback( object param );
>
> void ReBindOnUIThread( object param )
> {
> //This method will run in the main thread, we can touch the DataTable
> here:
> dt.Rows.Add(New Object() {"c", "d"})
> }
>
> Private Sub OnListchanged(ByVal s As Object, ByVal e As
> System.ComponentModel.ListChangedEventArgs)
>
> If b Then Return
> b = True ' don't want recursive calling
> //you can't touch the datatable here since we are in a different
> thread
> //dt.Rows.Add(New Object() {"c", "d"})
> //instead we rebind on the ui thread using the delegate
> this.Invoke( new UICallback( ReBindOnUIThread ), new object[] {
> <myobject>} );
>
> End Sub
>
> --
> Angel Saenz-Badillos [MS] Managed Providers
> This posting is provided "AS IS", with no warranties, and confers no
> rights.Please do not send email directly to this alias.
> This alias is for newsgroup purposes only.
> I am now blogging about ADO.NET: http://weblogs.asp.net/angelsb/
>
>
> >
> > "Urs Eichmann" <(E-Mail Removed)> wrote in message
> > news:(E-Mail Removed)...
> > > The following piece of code will run fine in .NET 1.1 without SP1, but
> > > will throw a NullReferenceException in SP1. Sadly, our app no longer
> > > runs with SP1, since it uses the same pattern (changing another row of
> > > data inside a ListChanged event of a DataView).
> > >
> > > Could please someone from Microsoft confirm this as a bug, and/or
> > > provide a workaround?
> > >
> > > Regards,
> > > Urs
> > >
> > >
> > > run the following as a console app:
> > >
> > > [VB.NET]
> > >
> > > Imports System.Data
> > >
> > > Module Module1
> > >
> > > Private dt As DataTable
> > > Private b As Boolean
> > >
> > > Sub Main()
> > >
> > > dt = New System.Data.DataTable
> > > dt.Columns.Add("Col1", GetType(String))
> > > dt.Columns.Add("Col2", GetType(String))
> > >
> > > Dim dv As New DataView(dt, "", "Col1",
> > > DataViewRowState.CurrentRows)
> > > AddHandler dv.ListChanged, AddressOf OnListchanged
> > > Dim dv2 As New DataView(dt, "", "Col2",
> > > DataViewRowState.CurrentRows)
> > > AddHandler dv2.ListChanged, AddressOf OnListchanged
> > >
> > > dt.Rows.Add(New Object() {"a", "b"}) ' NullRefException will be
> > > thrown here
> > >
> > > End Sub
> > >
> > > Private Sub OnListchanged(ByVal s As Object, ByVal e As
> > > System.ComponentModel.ListChangedEventArgs)
> > >
> > > If b Then Return
> > > b = True ' don't want recursive calling
> > >
> > > dt.Rows.Add(New Object() {"c", "d"})
> > >
> > > End Sub
> > >
> > > End Module

> >
> >

>
>
>

 
Reply With Quote
 
Urs Eichmann
Guest
Posts: n/a
 
      14th Sep 2004
Angel,
I don't agree with this answer, for these reasons:

a) the event occurs on the *same* thread as the main program, so it is
*not* a multi-threading problem (you can see for yourself if you watch
it in the debugger). So using "Invoke" won't make any difference IMHO.

b) It is *not* documented anywhere that "write" operations in an
EventHandler are not supported (at least I couldn't find this in the docs)

c) This code ran fine *without* SP1, in fact even back with .NET 1.0
there was no problem.

d) I couldn't find any hint in the SP1 docs that there are
incompatiblities to be expected in the DataView class between RTM and SP1.

I modified the repro program so that the event doesn't add a new row,
but changes the one just added. This is quite a common scenario: Apply
calculated values into certain columns of a new row which the user just
entered. This worked with pre-SP1 releases, but no longer works now. I
think this is a serious thing which shouldn't be taken on the light
shoulder. At least there should be a KB article which explains a workaround.

-------- Start Repro -----

Imports System.Data

Module Module1

Private dt As DataTable
Private dv, dv2 As DataView

Sub Main()

dt = New System.Data.DataTable
dt.Columns.Add("Col1", GetType(String))
dt.Columns.Add("Col2", GetType(String))

dv = New DataView(dt, "", "Col1", DataViewRowState.CurrentRows)
AddHandler dv.ListChanged, AddressOf OnListchanged

' The program only fails if there is more than one View, so
create a second one
dv2 = New DataView(dt, "", "Col2", DataViewRowState.CurrentRows)

dt.Rows.Add(New Object() {"a", "b"}) ' NullReferenceExeption
occurs here

End Sub

Private Sub X()

End Sub

Private Sub OnListchanged(ByVal s As Object, ByVal e As
System.ComponentModel.ListChangedEventArgs)

Static recusive As Boolean
If recusive Then Return
recusive = True

' Modify the row which was just added
Dim r As DataRowView = dv.Item(e.NewIndex)
r.BeginEdit()
r("Col2") = "xxx"
r.EndEdit()

End Sub

End Module

---- End Repro ---------


Best regards,
Urs


Angel Saenz-Badillos[MS] wrote:
> Uris,
> This is the response that I got from the dataset team:
> "This is an unsupported scenario. Any "write" operations on DataSet in an
> event handler will result in an unpredictable behavior.
> I'd suggest an alternative way of solving his scenario."
>
> I am not sure of what they mean with alternative solution, but it is true
> that "touching" the datatable in multiple threads is not supported. You can
> probably get arround this limitation by binding on the UI thread before
> calling the Add method with something like this (please excuse the code
> hack, I am doing copy paste from a c# project I had laying arround,
> hopefully you can get the idea of what to look for from here). The basic
> concept is that you can only call datatable add on the same thread in which
> you created the datatable, in this case we assume you created it on the main
> thread.
>
>
> delegate void UICallback( object param );
>
> void ReBindOnUIThread( object param )
> {
> //This method will run in the main thread, we can touch the DataTable
> here:
> dt.Rows.Add(New Object() {"c", "d"})
> }
>
> Private Sub OnListchanged(ByVal s As Object, ByVal e As
> System.ComponentModel.ListChangedEventArgs)
>
> If b Then Return
> b = True ' don't want recursive calling
> //you can't touch the datatable here since we are in a different
> thread
> //dt.Rows.Add(New Object() {"c", "d"})
> //instead we rebind on the ui thread using the delegate
> this.Invoke( new UICallback( ReBindOnUIThread ), new object[] {
> <myobject>} );
>
> End Sub
>

 
Reply With Quote
 
Angel Saenz-Badillos[MS]
Guest
Posts: n/a
 
      14th Sep 2004
Urs,
I have pointed Ravi from the dataset team to this thread, hopefully he will
be able to help.

--
Angel Saenz-Badillos [MS] Managed Providers
This posting is provided "AS IS", with no warranties, and confers no
rights.Please do not send email directly to this alias.
This alias is for newsgroup purposes only.
I am now blogging about ADO.NET: http://weblogs.asp.net/angelsb/




"Urs Eichmann" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Angel,
> I don't agree with this answer, for these reasons:
>
> a) the event occurs on the *same* thread as the main program, so it is
> *not* a multi-threading problem (you can see for yourself if you watch
> it in the debugger). So using "Invoke" won't make any difference IMHO.
>
> b) It is *not* documented anywhere that "write" operations in an
> EventHandler are not supported (at least I couldn't find this in the docs)
>
> c) This code ran fine *without* SP1, in fact even back with .NET 1.0
> there was no problem.
>
> d) I couldn't find any hint in the SP1 docs that there are
> incompatiblities to be expected in the DataView class between RTM and SP1.
>
> I modified the repro program so that the event doesn't add a new row,
> but changes the one just added. This is quite a common scenario: Apply
> calculated values into certain columns of a new row which the user just
> entered. This worked with pre-SP1 releases, but no longer works now. I
> think this is a serious thing which shouldn't be taken on the light
> shoulder. At least there should be a KB article which explains a

workaround.
>
> -------- Start Repro -----
>
> Imports System.Data
>
> Module Module1
>
> Private dt As DataTable
> Private dv, dv2 As DataView
>
> Sub Main()
>
> dt = New System.Data.DataTable
> dt.Columns.Add("Col1", GetType(String))
> dt.Columns.Add("Col2", GetType(String))
>
> dv = New DataView(dt, "", "Col1", DataViewRowState.CurrentRows)
> AddHandler dv.ListChanged, AddressOf OnListchanged
>
> ' The program only fails if there is more than one View, so
> create a second one
> dv2 = New DataView(dt, "", "Col2", DataViewRowState.CurrentRows)
>
> dt.Rows.Add(New Object() {"a", "b"}) ' NullReferenceExeption
> occurs here
>
> End Sub
>
> Private Sub X()
>
> End Sub
>
> Private Sub OnListchanged(ByVal s As Object, ByVal e As
> System.ComponentModel.ListChangedEventArgs)
>
> Static recusive As Boolean
> If recusive Then Return
> recusive = True
>
> ' Modify the row which was just added
> Dim r As DataRowView = dv.Item(e.NewIndex)
> r.BeginEdit()
> r("Col2") = "xxx"
> r.EndEdit()
>
> End Sub
>
> End Module
>
> ---- End Repro ---------
>
>
> Best regards,
> Urs
>
>
> Angel Saenz-Badillos[MS] wrote:
> > Uris,
> > This is the response that I got from the dataset team:
> > "This is an unsupported scenario. Any "write" operations on DataSet in

an
> > event handler will result in an unpredictable behavior.
> > I'd suggest an alternative way of solving his scenario."
> >
> > I am not sure of what they mean with alternative solution, but it is

true
> > that "touching" the datatable in multiple threads is not supported. You

can
> > probably get arround this limitation by binding on the UI thread before
> > calling the Add method with something like this (please excuse the code
> > hack, I am doing copy paste from a c# project I had laying arround,
> > hopefully you can get the idea of what to look for from here). The basic
> > concept is that you can only call datatable add on the same thread in

which
> > you created the datatable, in this case we assume you created it on the

main
> > thread.
> >
> >
> > delegate void UICallback( object param );
> >
> > void ReBindOnUIThread( object param )
> > {
> > //This method will run in the main thread, we can touch the

DataTable
> > here:
> > dt.Rows.Add(New Object() {"c", "d"})
> > }
> >
> > Private Sub OnListchanged(ByVal s As Object, ByVal e As
> > System.ComponentModel.ListChangedEventArgs)
> >
> > If b Then Return
> > b = True ' don't want recursive calling
> > //you can't touch the datatable here since we are in a

different
> > thread
> > //dt.Rows.Add(New Object() {"c", "d"})
> > //instead we rebind on the ui thread using the delegate
> > this.Invoke( new UICallback( ReBindOnUIThread ), new object[]

{
> > <myobject>} );
> >
> > End Sub
> >



 
Reply With Quote
 
=?Utf-8?B?VXJzIEVpY2htYW5u?=
Guest
Posts: n/a
 
      20th Sep 2004
Hi, didn't hear anything vom Ravi or anyone from MS regarding this issue.
We're currently blocked with our App...

Urs


"Angel Saenz-Badillos[MS]" wrote:

> Urs,
> I have pointed Ravi from the dataset team to this thread, hopefully he will
> be able to help.
>
> --
> Angel Saenz-Badillos [MS] Managed Providers
> This posting is provided "AS IS", with no warranties, and confers no
> rights.Please do not send email directly to this alias.
> This alias is for newsgroup purposes only.
> I am now blogging about ADO.NET: http://weblogs.asp.net/angelsb/
>
>
>
>
> "Urs Eichmann" <(E-Mail Removed)> wrote in message
> news:(E-Mail Removed)...
> > Angel,
> > I don't agree with this answer, for these reasons:
> >
> > a) the event occurs on the *same* thread as the main program, so it is
> > *not* a multi-threading problem (you can see for yourself if you watch
> > it in the debugger). So using "Invoke" won't make any difference IMHO.
> >
> > b) It is *not* documented anywhere that "write" operations in an
> > EventHandler are not supported (at least I couldn't find this in the docs)
> >
> > c) This code ran fine *without* SP1, in fact even back with .NET 1.0
> > there was no problem.
> >
> > d) I couldn't find any hint in the SP1 docs that there are
> > incompatiblities to be expected in the DataView class between RTM and SP1.
> >
> > I modified the repro program so that the event doesn't add a new row,
> > but changes the one just added. This is quite a common scenario: Apply
> > calculated values into certain columns of a new row which the user just
> > entered. This worked with pre-SP1 releases, but no longer works now. I
> > think this is a serious thing which shouldn't be taken on the light
> > shoulder. At least there should be a KB article which explains a

> workaround.
> >
> > -------- Start Repro -----
> >
> > Imports System.Data
> >
> > Module Module1
> >
> > Private dt As DataTable
> > Private dv, dv2 As DataView
> >
> > Sub Main()
> >
> > dt = New System.Data.DataTable
> > dt.Columns.Add("Col1", GetType(String))
> > dt.Columns.Add("Col2", GetType(String))
> >
> > dv = New DataView(dt, "", "Col1", DataViewRowState.CurrentRows)
> > AddHandler dv.ListChanged, AddressOf OnListchanged
> >
> > ' The program only fails if there is more than one View, so
> > create a second one
> > dv2 = New DataView(dt, "", "Col2", DataViewRowState.CurrentRows)
> >
> > dt.Rows.Add(New Object() {"a", "b"}) ' NullReferenceExeption
> > occurs here
> >
> > End Sub
> >
> > Private Sub X()
> >
> > End Sub
> >
> > Private Sub OnListchanged(ByVal s As Object, ByVal e As
> > System.ComponentModel.ListChangedEventArgs)
> >
> > Static recusive As Boolean
> > If recusive Then Return
> > recusive = True
> >
> > ' Modify the row which was just added
> > Dim r As DataRowView = dv.Item(e.NewIndex)
> > r.BeginEdit()
> > r("Col2") = "xxx"
> > r.EndEdit()
> >
> > End Sub
> >
> > End Module
> >
> > ---- End Repro ---------
> >
> >
> > Best regards,
> > Urs
> >
> >
> > Angel Saenz-Badillos[MS] wrote:
> > > Uris,
> > > This is the response that I got from the dataset team:
> > > "This is an unsupported scenario. Any "write" operations on DataSet in

> an
> > > event handler will result in an unpredictable behavior.
> > > I'd suggest an alternative way of solving his scenario."
> > >
> > > I am not sure of what they mean with alternative solution, but it is

> true
> > > that "touching" the datatable in multiple threads is not supported. You

> can
> > > probably get arround this limitation by binding on the UI thread before
> > > calling the Add method with something like this (please excuse the code
> > > hack, I am doing copy paste from a c# project I had laying arround,
> > > hopefully you can get the idea of what to look for from here). The basic
> > > concept is that you can only call datatable add on the same thread in

> which
> > > you created the datatable, in this case we assume you created it on the

> main
> > > thread.
> > >
> > >
> > > delegate void UICallback( object param );
> > >
> > > void ReBindOnUIThread( object param )
> > > {
> > > //This method will run in the main thread, we can touch the

> DataTable
> > > here:
> > > dt.Rows.Add(New Object() {"c", "d"})
> > > }
> > >
> > > Private Sub OnListchanged(ByVal s As Object, ByVal e As
> > > System.ComponentModel.ListChangedEventArgs)
> > >
> > > If b Then Return
> > > b = True ' don't want recursive calling
> > > //you can't touch the datatable here since we are in a

> different
> > > thread
> > > //dt.Rows.Add(New Object() {"c", "d"})
> > > //instead we rebind on the ui thread using the delegate
> > > this.Invoke( new UICallback( ReBindOnUIThread ), new object[]

> {
> > > <myobject>} );
> > >
> > > End Sub
> > >

>
>
>

 
Reply With Quote
 
Angel Saenz-Badillos[MS]
Guest
Posts: n/a
 
      21st Sep 2004
Urs,
I have sent another email, hopefully he can contact you shortly.

Thanks,
--
Angel Saenz-Badillos [MS] Managed Providers
This posting is provided "AS IS", with no warranties, and confers no
rights.Please do not send email directly to this alias.
This alias is for newsgroup purposes only.
I am now blogging about ADO.NET: http://weblogs.asp.net/angelsb/




"Urs Eichmann" <Urs (E-Mail Removed)> wrote in message
news:277179B1-0303-47B9-9A35-(E-Mail Removed)...
> Hi, didn't hear anything vom Ravi or anyone from MS regarding this issue.
> We're currently blocked with our App...
>
> Urs
>
>
> "Angel Saenz-Badillos[MS]" wrote:
>
> > Urs,
> > I have pointed Ravi from the dataset team to this thread, hopefully he

will
> > be able to help.
> >
> > --
> > Angel Saenz-Badillos [MS] Managed Providers
> > This posting is provided "AS IS", with no warranties, and confers no
> > rights.Please do not send email directly to this alias.
> > This alias is for newsgroup purposes only.
> > I am now blogging about ADO.NET: http://weblogs.asp.net/angelsb/
> >
> >
> >
> >
> > "Urs Eichmann" <(E-Mail Removed)> wrote in message
> > news:(E-Mail Removed)...
> > > Angel,
> > > I don't agree with this answer, for these reasons:
> > >
> > > a) the event occurs on the *same* thread as the main program, so it is
> > > *not* a multi-threading problem (you can see for yourself if you watch
> > > it in the debugger). So using "Invoke" won't make any difference IMHO.
> > >
> > > b) It is *not* documented anywhere that "write" operations in an
> > > EventHandler are not supported (at least I couldn't find this in the

docs)
> > >
> > > c) This code ran fine *without* SP1, in fact even back with .NET 1.0
> > > there was no problem.
> > >
> > > d) I couldn't find any hint in the SP1 docs that there are
> > > incompatiblities to be expected in the DataView class between RTM and

SP1.
> > >
> > > I modified the repro program so that the event doesn't add a new row,
> > > but changes the one just added. This is quite a common scenario: Apply
> > > calculated values into certain columns of a new row which the user

just
> > > entered. This worked with pre-SP1 releases, but no longer works now. I
> > > think this is a serious thing which shouldn't be taken on the light
> > > shoulder. At least there should be a KB article which explains a

> > workaround.
> > >
> > > -------- Start Repro -----
> > >
> > > Imports System.Data
> > >
> > > Module Module1
> > >
> > > Private dt As DataTable
> > > Private dv, dv2 As DataView
> > >
> > > Sub Main()
> > >
> > > dt = New System.Data.DataTable
> > > dt.Columns.Add("Col1", GetType(String))
> > > dt.Columns.Add("Col2", GetType(String))
> > >
> > > dv = New DataView(dt, "", "Col1",

DataViewRowState.CurrentRows)
> > > AddHandler dv.ListChanged, AddressOf OnListchanged
> > >
> > > ' The program only fails if there is more than one View, so
> > > create a second one
> > > dv2 = New DataView(dt, "", "Col2",

DataViewRowState.CurrentRows)
> > >
> > > dt.Rows.Add(New Object() {"a", "b"}) ' NullReferenceExeption
> > > occurs here
> > >
> > > End Sub
> > >
> > > Private Sub X()
> > >
> > > End Sub
> > >
> > > Private Sub OnListchanged(ByVal s As Object, ByVal e As
> > > System.ComponentModel.ListChangedEventArgs)
> > >
> > > Static recusive As Boolean
> > > If recusive Then Return
> > > recusive = True
> > >
> > > ' Modify the row which was just added
> > > Dim r As DataRowView = dv.Item(e.NewIndex)
> > > r.BeginEdit()
> > > r("Col2") = "xxx"
> > > r.EndEdit()
> > >
> > > End Sub
> > >
> > > End Module
> > >
> > > ---- End Repro ---------
> > >
> > >
> > > Best regards,
> > > Urs
> > >
> > >
> > > Angel Saenz-Badillos[MS] wrote:
> > > > Uris,
> > > > This is the response that I got from the dataset team:
> > > > "This is an unsupported scenario. Any "write" operations on DataSet

in
> > an
> > > > event handler will result in an unpredictable behavior.
> > > > I'd suggest an alternative way of solving his scenario."
> > > >
> > > > I am not sure of what they mean with alternative solution, but it is

> > true
> > > > that "touching" the datatable in multiple threads is not supported.

You
> > can
> > > > probably get arround this limitation by binding on the UI thread

before
> > > > calling the Add method with something like this (please excuse the

code
> > > > hack, I am doing copy paste from a c# project I had laying arround,
> > > > hopefully you can get the idea of what to look for from here). The

basic
> > > > concept is that you can only call datatable add on the same thread

in
> > which
> > > > you created the datatable, in this case we assume you created it on

the
> > main
> > > > thread.
> > > >
> > > >
> > > > delegate void UICallback( object param );
> > > >
> > > > void ReBindOnUIThread( object param )
> > > > {
> > > > //This method will run in the main thread, we can touch the

> > DataTable
> > > > here:
> > > > dt.Rows.Add(New Object() {"c", "d"})
> > > > }
> > > >
> > > > Private Sub OnListchanged(ByVal s As Object, ByVal e As
> > > > System.ComponentModel.ListChangedEventArgs)
> > > >
> > > > If b Then Return
> > > > b = True ' don't want recursive calling
> > > > //you can't touch the datatable here since we are in a

> > different
> > > > thread
> > > > //dt.Rows.Add(New Object() {"c", "d"})
> > > > //instead we rebind on the ui thread using the delegate
> > > > this.Invoke( new UICallback( ReBindOnUIThread ), new

object[]
> > {
> > > > <myobject>} );
> > > >
> > > > End Sub
> > > >

> >
> >
> >



 
Reply With Quote
 
=?Utf-8?B?R29yYW4gU3RpamFjaWM=?=
Guest
Posts: n/a
 
      3rd Mar 2005
Did anybody ever get a resolution to this problem? We are dealing with the
same problem.

Thanks

"Angel Saenz-Badillos[MS]" wrote:

> Urs,
> I have sent another email, hopefully he can contact you shortly.
>
> Thanks,
> --
> Angel Saenz-Badillos [MS] Managed Providers
> This posting is provided "AS IS", with no warranties, and confers no
> rights.Please do not send email directly to this alias.
> This alias is for newsgroup purposes only.
> I am now blogging about ADO.NET: http://weblogs.asp.net/angelsb/
>
>
>
>
> "Urs Eichmann" <Urs (E-Mail Removed)> wrote in message
> news:277179B1-0303-47B9-9A35-(E-Mail Removed)...
> > Hi, didn't hear anything vom Ravi or anyone from MS regarding this issue.
> > We're currently blocked with our App...
> >
> > Urs
> >
> >
> > "Angel Saenz-Badillos[MS]" wrote:
> >
> > > Urs,
> > > I have pointed Ravi from the dataset team to this thread, hopefully he

> will
> > > be able to help.
> > >
> > > --
> > > Angel Saenz-Badillos [MS] Managed Providers
> > > This posting is provided "AS IS", with no warranties, and confers no
> > > rights.Please do not send email directly to this alias.
> > > This alias is for newsgroup purposes only.
> > > I am now blogging about ADO.NET: http://weblogs.asp.net/angelsb/
> > >
> > >
> > >
> > >
> > > "Urs Eichmann" <(E-Mail Removed)> wrote in message
> > > news:(E-Mail Removed)...
> > > > Angel,
> > > > I don't agree with this answer, for these reasons:
> > > >
> > > > a) the event occurs on the *same* thread as the main program, so it is
> > > > *not* a multi-threading problem (you can see for yourself if you watch
> > > > it in the debugger). So using "Invoke" won't make any difference IMHO.
> > > >
> > > > b) It is *not* documented anywhere that "write" operations in an
> > > > EventHandler are not supported (at least I couldn't find this in the

> docs)
> > > >
> > > > c) This code ran fine *without* SP1, in fact even back with .NET 1.0
> > > > there was no problem.
> > > >
> > > > d) I couldn't find any hint in the SP1 docs that there are
> > > > incompatiblities to be expected in the DataView class between RTM and

> SP1.
> > > >
> > > > I modified the repro program so that the event doesn't add a new row,
> > > > but changes the one just added. This is quite a common scenario: Apply
> > > > calculated values into certain columns of a new row which the user

> just
> > > > entered. This worked with pre-SP1 releases, but no longer works now. I
> > > > think this is a serious thing which shouldn't be taken on the light
> > > > shoulder. At least there should be a KB article which explains a
> > > workaround.
> > > >
> > > > -------- Start Repro -----
> > > >
> > > > Imports System.Data
> > > >
> > > > Module Module1
> > > >
> > > > Private dt As DataTable
> > > > Private dv, dv2 As DataView
> > > >
> > > > Sub Main()
> > > >
> > > > dt = New System.Data.DataTable
> > > > dt.Columns.Add("Col1", GetType(String))
> > > > dt.Columns.Add("Col2", GetType(String))
> > > >
> > > > dv = New DataView(dt, "", "Col1",

> DataViewRowState.CurrentRows)
> > > > AddHandler dv.ListChanged, AddressOf OnListchanged
> > > >
> > > > ' The program only fails if there is more than one View, so
> > > > create a second one
> > > > dv2 = New DataView(dt, "", "Col2",

> DataViewRowState.CurrentRows)
> > > >
> > > > dt.Rows.Add(New Object() {"a", "b"}) ' NullReferenceExeption
> > > > occurs here
> > > >
> > > > End Sub
> > > >
> > > > Private Sub X()
> > > >
> > > > End Sub
> > > >
> > > > Private Sub OnListchanged(ByVal s As Object, ByVal e As
> > > > System.ComponentModel.ListChangedEventArgs)
> > > >
> > > > Static recusive As Boolean
> > > > If recusive Then Return
> > > > recusive = True
> > > >
> > > > ' Modify the row which was just added
> > > > Dim r As DataRowView = dv.Item(e.NewIndex)
> > > > r.BeginEdit()
> > > > r("Col2") = "xxx"
> > > > r.EndEdit()
> > > >
> > > > End Sub
> > > >
> > > > End Module
> > > >
> > > > ---- End Repro ---------
> > > >
> > > >
> > > > Best regards,
> > > > Urs
> > > >
> > > >
> > > > Angel Saenz-Badillos[MS] wrote:
> > > > > Uris,
> > > > > This is the response that I got from the dataset team:
> > > > > "This is an unsupported scenario. Any "write" operations on DataSet

> in
> > > an
> > > > > event handler will result in an unpredictable behavior.
> > > > > I'd suggest an alternative way of solving his scenario."
> > > > >
> > > > > I am not sure of what they mean with alternative solution, but it is
> > > true
> > > > > that "touching" the datatable in multiple threads is not supported.

> You
> > > can
> > > > > probably get arround this limitation by binding on the UI thread

> before
> > > > > calling the Add method with something like this (please excuse the

> code
> > > > > hack, I am doing copy paste from a c# project I had laying arround,
> > > > > hopefully you can get the idea of what to look for from here). The

> basic
> > > > > concept is that you can only call datatable add on the same thread

> in
> > > which
> > > > > you created the datatable, in this case we assume you created it on

> the
> > > main
> > > > > thread.
> > > > >
> > > > >
> > > > > delegate void UICallback( object param );
> > > > >
> > > > > void ReBindOnUIThread( object param )
> > > > > {
> > > > > //This method will run in the main thread, we can touch the
> > > DataTable
> > > > > here:
> > > > > dt.Rows.Add(New Object() {"c", "d"})
> > > > > }
> > > > >
> > > > > Private Sub OnListchanged(ByVal s As Object, ByVal e As
> > > > > System.ComponentModel.ListChangedEventArgs)
> > > > >
> > > > > If b Then Return
> > > > > b = True ' don't want recursive calling
> > > > > //you can't touch the datatable here since we are in a
> > > different
> > > > > thread
> > > > > //dt.Rows.Add(New Object() {"c", "d"})
> > > > > //instead we rebind on the ui thread using the delegate
> > > > > this.Invoke( new UICallback( ReBindOnUIThread ), new

> object[]
> > > {
> > > > > <myobject>} );
> > > > >
> > > > > End Sub
> > > > >
> > >
> > >
> > >

>
>
>

 
Reply With Quote
 
=?Utf-8?B?R2FyZXRo?=
Guest
Posts: n/a
 
      12th Mar 2005
Hi,
I am also having simliar problem with SP1, except I have datagrid bound to
dataset in runtime any changes made withing the datagrid throws a "Error when
committing row to the original data store" this occurs during rowupdating
event i think. anyway my program worked fine without SP 1 now its broken, and
not sure what to do to fix it. maybe i have made error in my code but somehow
dont think so because cannot debug as it seems to be within the datagrid or
dataset code. not sure. if anyone can help would be great.
thanks
 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Breaking change in MS DLL's ? Rob Microsoft VC .NET 11 4th Nov 2009 02:58 AM
CHR(0) - breaking change in CF 3.5? Benjamin Lukner Microsoft Dot NET Compact Framework 7 29th May 2009 01:19 AM
RE: Entity Framework issue - no change notification provided for assoc zihotki Microsoft ADO .NET 0 9th Sep 2008 08:10 AM
breaking up a String into an array of chars and adding to datatable Paulers Microsoft VB .NET 6 15th Jan 2007 03:31 AM
SB Live! Player 5.1 with 4 repro under XP Eskimak Windows XP Drivers 0 16th Nov 2003 07:59 PM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 04:39 PM.