|
dev
newsgroups
|
|||||||||||||||||||||||
|
|||||||||||||||||||||||
Deadlock ProblemI have a MDI WinForm Client App. I keep a static Master DataSet and a static Master Hashtable. When I connect to the Server, it sends me a Master DataSet and I copy it to the static Master DataSetand also create a static Master Hashtable with DataRow as value and Symbol as a key. I need Master Hashtable for fast retrival. That was the initial connect. Updates from server also comes as a Hashtable with name-value pairs via TIBCO Message Bus. I retrive the Symbol using "SYMBOL" as key from the update Hashtable, get the DataRow from static Master Hashtable using that symbol and update the DataRow with name-value update Hashtable. Inside MDI Form I can create n number of forms, each from would have a different view on the static Master DataSet using .NET DataView. Everything runs fine. All the views get updates, since all are bound to a DataView on a Static Master DataSet. Then suddenly after 2-3 hours, the client doesn't respond and the size of the TIBCO message bus grows. It hung up on DataRow.AcceptChanges() method. My question is, is it alright to update the DataSet on a thread different than a thread that created the Grid to which the DataSet is bound? I know that when you update a control you have to call Invoke or Begin Invoke on that control and etc. etc. ..... If its not the right way of doing then I can't afford to update the DataSet on the main thread that created the forms and controls (including grid) because the number of updates are too high (10000 per minutes with ~90 columns in a row) and that would affect user interaction with the application. Is there any workaround? Any help/idea is appreciated. Thanks a lot, Lalit This is not a deadlock problem. It's likely a performance issue or an
unhandled exception. The dataaset has thread affinity to the main thread and its also tied to the dataview object so you need to correctly marshal your update calls using invoke. I don't understand why you have a dataset and a hashtable though. You can do without the one. I'm not sure how much performance improvement you are getting from a hashtable as opposed to a dataset find routine. The dataset find routine uses an optimized indexer underneath so retrievals are fast. Another problem i see is that you have a master dataset but it doesn't appear to be wrapped in a class. So you can possibly cause the dataset grief if multiple forms trigger the acceptchanges function within a short space of time or at the same time. Datasets weren't meant for concurrent access. -- Show quoteHide quoteRegards, Alvin Bruney [MVP ASP.NET] [Shameless Author plug] The Microsoft Office Web Components Black Book with .NET Now Available @ http://tinyurl.com/27cok ---------------------------------------------------------- "Lalit" <La***@discussions.microsoft.com> wrote in message news:D623E904-E0C1-4686-B70B-ED0E35F94187@microsoft.com... > Hi, > I have a MDI WinForm Client App. I keep a static Master DataSet and a > static > Master Hashtable. When I connect to the Server, it sends me a Master > DataSet > and I copy it to the static Master DataSetand also create a static Master > Hashtable with DataRow as value and Symbol as a key. I need Master > Hashtable > for fast retrival. > > That was the initial connect. Updates from server also comes as a > Hashtable > with name-value pairs via TIBCO Message Bus. I retrive the Symbol using > "SYMBOL" as key from the update Hashtable, get the DataRow from static > Master > Hashtable using that symbol and update the DataRow with name-value update > Hashtable. > > Inside MDI Form I can create n number of forms, each from would have a > different view on the static Master DataSet using .NET DataView. > > Everything runs fine. All the views get updates, since all are bound to a > DataView on a Static Master DataSet. Then suddenly after 2-3 hours, the > client doesn't respond and the size of the TIBCO message bus grows. > > It hung up on DataRow.AcceptChanges() method. > > My question is, is it alright to update the DataSet on a thread different > than a thread that created the Grid to which the DataSet is bound? I know > that when you update a control you have to call Invoke or Begin Invoke on > that control and etc. etc. ..... > > If its not the right way of doing then I can't afford to update the > DataSet > on the main thread that created the forms and controls (including grid) > because the number of updates are too high (10000 per minutes with ~90 > columns in a row) and that would affect user interaction with the > application. > > Is there any workaround? > > Any help/idea is appreciated. > > Thanks a lot, > Lalit > Alvin,
Thanks for the reply. I didn't know that DataSet too has thread affinity to the thread on which it was created (not the main thread, typo I guess). In any case, I am updating the DataSet on the same thread that created it. Find routine is too slow for large number of hits. DataSet is updated by a single thread all the time, in a sequential manner. Its not the Form that updates the DataSet, its the message that TIBCO sends as a Hashtable. Since the Grid is bound to that DataSet and each instance of that form has a DataView on this Master DataSet, the view is updated as soon as the Row is updated. Probablity of it being a performance issues or unhandles exception is less because I am logging all the exception that I handle and I am handling all the exceptions. My question still remain the same: - is it alright to update the DataSet on a thread different than a thread (its still the same thread that created the DataSet) that created the Grid to which the DataSet is bound? - If its not the right way of doing then I can't afford to update the DataSet on the main thread that created the forms and controls (including grid) because the number of updates are too high (10000 per minutes with ~90 columns in a row) and that would affect user interaction with the application. Is there any workaround? Thanks a lot. Lalit Show quoteHide quote "Alvin Bruney [MVP]" wrote: > This is not a deadlock problem. It's likely a performance issue or an > unhandled exception. > The dataaset has thread affinity to the main thread and its also tied to the > dataview object so you need to correctly marshal your update calls using > invoke. I don't understand why you have a dataset and a hashtable though. > You can do without the one. I'm not sure how much performance improvement > you are getting from a hashtable as opposed to a dataset find routine. The > dataset find routine uses an optimized indexer underneath so retrievals are > fast. > > Another problem i see is that you have a master dataset but it doesn't > appear to be wrapped in a class. So you can possibly cause the dataset grief > if multiple forms trigger the acceptchanges function within a short space of > time or at the same time. Datasets weren't meant for concurrent access. > -- > Regards, > Alvin Bruney [MVP ASP.NET] > > [Shameless Author plug] > The Microsoft Office Web Components Black Book with .NET > Now Available @ http://tinyurl.com/27cok > ---------------------------------------------------------- > My question still remain the same: Which find routine, the dataset's find routine or a find routine that you > - is it alright to update the DataSet on a thread different than a thread > (its still the same thread that created the DataSet) that created the Grid > to > which the DataSet is bound? Yes. > Find routine is too slow for large number of hits. implemented separately? Did you test this? > DataSet is updated by a single thread all the time, in a sequential How can this possibly be? You have 10,000+ updates being triggered by TIBCO > manner. thru a hashtable on a per form basis, each form being tied to a view which is sourced from a global dataset. Unless TIBCO is throttling the updates sequentially, you stand a chance of concurrent access. I suspect, you have no type of protection on that global dataset but you are using the dataset as if it was synchronized for access. That is my leading theory at this time. It is time to see some relevant code. -- Show quoteHide quoteRegards, Alvin Bruney [MVP ASP.NET] [Shameless Author plug] The Microsoft Office Web Components Black Book with .NET Now Available @ http://www.lulu.com/owc ---------------------------------------------------------- "Lalit" <La***@discussions.microsoft.com> wrote in message news:FAE3C694-5CD9-46F3-9286-E3F83DFA5524@microsoft.com... > Alvin, > Thanks for the reply. > > I didn't know that DataSet too has thread affinity to the thread on which > it > was created (not the main thread, typo I guess). In any case, I am > updating > the DataSet on the same thread that created it. > > Find routine is too slow for large number of hits. > > DataSet is updated by a single thread all the time, in a sequential > manner. > Its not the Form that updates the DataSet, its the message that TIBCO > sends > as a Hashtable. Since the Grid is bound to that DataSet and each instance > of > that form has a DataView on this Master DataSet, the view is updated as > soon > as the Row is updated. > > Probablity of it being a performance issues or unhandles exception is less > because I am logging all the exception that I handle and I am handling all > the exceptions. > > My question still remain the same: > - is it alright to update the DataSet on a thread different than a thread > (its still the same thread that created the DataSet) that created the Grid > to > which the DataSet is bound? > > - If its not the right way of doing then I can't afford to update the > DataSet on the main thread that created the forms and controls (including > grid) because the number of updates are too high (10000 per minutes with > ~90 > columns in a row) and that would affect user interaction with the > application. > Is there any workaround? > > Thanks a lot. > Lalit > > "Alvin Bruney [MVP]" wrote: > >> This is not a deadlock problem. It's likely a performance issue or an >> unhandled exception. >> The dataaset has thread affinity to the main thread and its also tied to >> the >> dataview object so you need to correctly marshal your update calls using >> invoke. I don't understand why you have a dataset and a hashtable though. >> You can do without the one. I'm not sure how much performance improvement >> you are getting from a hashtable as opposed to a dataset find routine. >> The >> dataset find routine uses an optimized indexer underneath so retrievals >> are >> fast. >> >> Another problem i see is that you have a master dataset but it doesn't >> appear to be wrapped in a class. So you can possibly cause the dataset >> grief >> if multiple forms trigger the acceptchanges function within a short space >> of >> time or at the same time. Datasets weren't meant for concurrent access. >> -- >> Regards, >> Alvin Bruney [MVP ASP.NET] >> >> [Shameless Author plug] >> The Microsoft Office Web Components Black Book with .NET >> Now Available @ http://tinyurl.com/27cok >> ---------------------------------------------------------- > As per my investigations Find method of DataSet is slower than using Hashtable.
If you could tell me you e-mail ID I would like you to take a look at the code. I do not see a way to attach a file on this newsgroup. Yeah TIBCO is throttling the updates sequentially. If I need to make the process faster I need to create a thread as soon as I get the update and then update the DataSet, but I am not doing it at this point in time. Thanks, Lalit Show quoteHide quote "Alvin Bruney [MVP]" wrote: > > My question still remain the same: > > - is it alright to update the DataSet on a thread different than a thread > > (its still the same thread that created the DataSet) that created the Grid > > to > > which the DataSet is bound? > Yes. > > > Find routine is too slow for large number of hits. > Which find routine, the dataset's find routine or a find routine that you > implemented separately? Did you test this? > > > DataSet is updated by a single thread all the time, in a sequential > > manner. > How can this possibly be? You have 10,000+ updates being triggered by TIBCO > thru a hashtable on a per form basis, each form being tied to a view which > is sourced from a global dataset. Unless TIBCO is throttling the updates > sequentially, you stand a chance of concurrent access. I suspect, you have > no type of protection on that global dataset but you are using the dataset > as if it was synchronized for access. That is my leading theory at this > time. > > It is time to see some relevant code. > > -- > Regards, > Alvin Bruney [MVP ASP.NET] > > [Shameless Author plug] > The Microsoft Office Web Components Black Book with .NET > Now Available @ http://www.lulu.com/owc > ---------------------------------------------------------- > > > "Lalit" <La***@discussions.microsoft.com> wrote in message > news:FAE3C694-5CD9-46F3-9286-E3F83DFA5524@microsoft.com... > > Alvin, > > Thanks for the reply. > > > > I didn't know that DataSet too has thread affinity to the thread on which > > it > > was created (not the main thread, typo I guess). In any case, I am > > updating > > the DataSet on the same thread that created it. > > > > Find routine is too slow for large number of hits. > > > > DataSet is updated by a single thread all the time, in a sequential > > manner. > > Its not the Form that updates the DataSet, its the message that TIBCO > > sends > > as a Hashtable. Since the Grid is bound to that DataSet and each instance > > of > > that form has a DataView on this Master DataSet, the view is updated as > > soon > > as the Row is updated. > > > > Probablity of it being a performance issues or unhandles exception is less > > because I am logging all the exception that I handle and I am handling all > > the exceptions. > > > > My question still remain the same: > > - is it alright to update the DataSet on a thread different than a thread > > (its still the same thread that created the DataSet) that created the Grid > > to > > which the DataSet is bound? > > > > - If its not the right way of doing then I can't afford to update the > > DataSet on the main thread that created the forms and controls (including > > grid) because the number of updates are too high (10000 per minutes with > > ~90 > > columns in a row) and that would affect user interaction with the > > application. > > Is there any workaround? > > > > Thanks a lot. > > Lalit > > > > "Alvin Bruney [MVP]" wrote: > > > >> This is not a deadlock problem. It's likely a performance issue or an > >> unhandled exception. > >> The dataaset has thread affinity to the main thread and its also tied to > >> the > >> dataview object so you need to correctly marshal your update calls using > >> invoke. I don't understand why you have a dataset and a hashtable though. > >> You can do without the one. I'm not sure how much performance improvement > >> you are getting from a hashtable as opposed to a dataset find routine. > >> The > >> dataset find routine uses an optimized indexer underneath so retrievals > >> are > >> fast. > >> > >> Another problem i see is that you have a master dataset but it doesn't > >> appear to be wrapped in a class. So you can possibly cause the dataset > >> grief > >> if multiple forms trigger the acceptchanges function within a short space > >> of > >> time or at the same time. Datasets weren't meant for concurrent access. > >> -- > >> Regards, > >> Alvin Bruney [MVP ASP.NET] > >> > >> [Shameless Author plug] > >> The Microsoft Office Web Components Black Book with .NET > >> Now Available @ http://tinyurl.com/27cok > >> ---------------------------------------------------------- > > > > > See this link, http://www.yoda.arachsys.com/csharp/complete.html
then post -- Show quoteHide quoteRegards, Alvin Bruney [MVP ASP.NET] [Shameless Author plug] The Microsoft Office Web Components Black Book with .NET Now Available @ http://www.lulu.com/owc ---------------------------------------------------------- "Lalit" <La***@discussions.microsoft.com> wrote in message news:E3AE5D59-A549-42CD-AEA7-85CEA8B963A4@microsoft.com... > As per my investigations Find method of DataSet is slower than using > Hashtable. > > If you could tell me you e-mail ID I would like you to take a look at the > code. I do not see a way to attach a file on this newsgroup. > > Yeah TIBCO is throttling the updates sequentially. If I need to make the > process faster I need to create a thread as soon as I get the update and > then > update the DataSet, but I am not doing it at this point in time. > > Thanks, > Lalit > > "Alvin Bruney [MVP]" wrote: > >> > My question still remain the same: >> > - is it alright to update the DataSet on a thread different than a >> > thread >> > (its still the same thread that created the DataSet) that created the >> > Grid >> > to >> > which the DataSet is bound? >> Yes. >> >> > Find routine is too slow for large number of hits. >> Which find routine, the dataset's find routine or a find routine that you >> implemented separately? Did you test this? >> >> > DataSet is updated by a single thread all the time, in a sequential >> > manner. >> How can this possibly be? You have 10,000+ updates being triggered by >> TIBCO >> thru a hashtable on a per form basis, each form being tied to a view >> which >> is sourced from a global dataset. Unless TIBCO is throttling the updates >> sequentially, you stand a chance of concurrent access. I suspect, you >> have >> no type of protection on that global dataset but you are using the >> dataset >> as if it was synchronized for access. That is my leading theory at this >> time. >> >> It is time to see some relevant code. >> >> -- >> Regards, >> Alvin Bruney [MVP ASP.NET] >> >> [Shameless Author plug] >> The Microsoft Office Web Components Black Book with .NET >> Now Available @ http://www.lulu.com/owc >> ---------------------------------------------------------- >> >> >> "Lalit" <La***@discussions.microsoft.com> wrote in message >> news:FAE3C694-5CD9-46F3-9286-E3F83DFA5524@microsoft.com... >> > Alvin, >> > Thanks for the reply. >> > >> > I didn't know that DataSet too has thread affinity to the thread on >> > which >> > it >> > was created (not the main thread, typo I guess). In any case, I am >> > updating >> > the DataSet on the same thread that created it. >> > >> > Find routine is too slow for large number of hits. >> > >> > DataSet is updated by a single thread all the time, in a sequential >> > manner. >> > Its not the Form that updates the DataSet, its the message that TIBCO >> > sends >> > as a Hashtable. Since the Grid is bound to that DataSet and each >> > instance >> > of >> > that form has a DataView on this Master DataSet, the view is updated as >> > soon >> > as the Row is updated. >> > >> > Probablity of it being a performance issues or unhandles exception is >> > less >> > because I am logging all the exception that I handle and I am handling >> > all >> > the exceptions. >> > >> > My question still remain the same: >> > - is it alright to update the DataSet on a thread different than a >> > thread >> > (its still the same thread that created the DataSet) that created the >> > Grid >> > to >> > which the DataSet is bound? >> > >> > - If its not the right way of doing then I can't afford to update the >> > DataSet on the main thread that created the forms and controls >> > (including >> > grid) because the number of updates are too high (10000 per minutes >> > with >> > ~90 >> > columns in a row) and that would affect user interaction with the >> > application. >> > Is there any workaround? >> > >> > Thanks a lot. >> > Lalit >> > >> > "Alvin Bruney [MVP]" wrote: >> > >> >> This is not a deadlock problem. It's likely a performance issue or an >> >> unhandled exception. >> >> The dataaset has thread affinity to the main thread and its also tied >> >> to >> >> the >> >> dataview object so you need to correctly marshal your update calls >> >> using >> >> invoke. I don't understand why you have a dataset and a hashtable >> >> though. >> >> You can do without the one. I'm not sure how much performance >> >> improvement >> >> you are getting from a hashtable as opposed to a dataset find routine. >> >> The >> >> dataset find routine uses an optimized indexer underneath so >> >> retrievals >> >> are >> >> fast. >> >> >> >> Another problem i see is that you have a master dataset but it doesn't >> >> appear to be wrapped in a class. So you can possibly cause the dataset >> >> grief >> >> if multiple forms trigger the acceptchanges function within a short >> >> space >> >> of >> >> time or at the same time. Datasets weren't meant for concurrent >> >> access. >> >> -- >> >> Regards, >> >> Alvin Bruney [MVP ASP.NET] >> >> >> >> [Shameless Author plug] >> >> The Microsoft Office Web Components Black Book with .NET >> >> Now Available @ http://tinyurl.com/27cok >> >> ---------------------------------------------------------- >> > >> >> >> I am pasting the code that shows that Hash is faster than Find Method of
RowCollection. At this point in time I can't post the code that is within your specs and that reproduce the deadlock because of time constraint. I can give you some of the classes as it is just to look at, if you want. Thanks a lot, Lalit using System; using System.Data; using System.Collections; public class MyClass { public static void Main() { RL(); } private static void RL() { try { Hashtable hash = new Hashtable(); DataSet ds = new DataSet(); DataTable table = new DataTable(); table.Columns.Add("Id", Type.GetType("System.Int32")); table.Columns.Add("Name", Type.GetType("System.String")); table.PrimaryKey = new DataColumn[] {table.Columns["Id"]}; ds.Tables.Add(table); for(int i = 0; i < 1000000; i++) { DataRow dr = table.NewRow(); dr["Id"] = i; dr["Name"] = i.ToString(); hash.Add(i, dr); table.Rows.Add(dr); } Console.WriteLine(ds.Tables[0].Rows.Count.ToString()); DateTime t1 = DateTime.Now; for(int i = 0; i < 1000000; i++) { int j = new Random(unchecked((int)DateTime.Now.Ticks)).Next(1000000 - 1); DataRow dr = table.NewRow(); dr["Id"] = j; dr["Name"] = j.ToString(); DataRow r = ds.Tables[0].Rows.Find(j); } DateTime t2 = DateTime.Now; Console.WriteLine(t2-t1); t1 = DateTime.Now; for(int i = 0; i < 1000000; i++) { int j = new Random(unchecked((int)DateTime.Now.Ticks)).Next(1000000 - 1); DataRow dr = table.NewRow(); dr["Id"] = j; dr["Name"] = j.ToString(); DataRow r = (DataRow) hash[j]; } t2 = DateTime.Now; Console.WriteLine(t2-t1); Console.ReadLine(); } catch(Exception e) { Console.WriteLine(e.ToString()); } } } public class Person { private int id; public int Id { get { return id; } set { id = value; } } private string name; public string Name { get { return name; } set { name = value; } } } <"Alvin Bruney [MVP]" <vapor at steaming post office>> wrote: Just to clarify - I don't think DataSets naturally have thread affinity > This is not a deadlock problem. It's likely a performance issue or an > unhandled exception. > The dataaset has thread affinity to the main thread and its also tied to the > dataview object so you need to correctly marshal your update calls using > invoke. - it's when modifying them makes a UI do something that you have problems. If you can unbind all the controls from the DataSet, make the modifications, then put the bindings in again, I think that's fine. (Alternatively, have a "working" DataSet and a "display" DataSet, and when all the work has been done, make all the changes again in the display version.) That's the way I understand it, but I may be wrong, in which case I definitely want to know! -- Jon Skeet - <sk***@pobox.com> http://www.pobox.com/~skeet If replying to the group, please do not mail me too DataSet is too big, 5000 rows with ~90 columns, and update are coming at
~10000 per minute. Unbinding and binding again would definitelty affect the performance and there could be n number of instance of a form that would display different views on the same dataset. Lalit Show quoteHide quote "Jon Skeet [C# MVP]" wrote: > <"Alvin Bruney [MVP]" <vapor at steaming post office>> wrote: > > This is not a deadlock problem. It's likely a performance issue or an > > unhandled exception. > > The dataaset has thread affinity to the main thread and its also tied to the > > dataview object so you need to correctly marshal your update calls using > > invoke. > > Just to clarify - I don't think DataSets naturally have thread affinity > - it's when modifying them makes a UI do something that you have > problems. If you can unbind all the controls from the DataSet, make the > modifications, then put the bindings in again, I think that's fine. > (Alternatively, have a "working" DataSet and a "display" DataSet, and > when all the work has been done, make all the changes again in the > display version.) > > That's the way I understand it, but I may be wrong, in which case I > definitely want to know! > > -- > Jon Skeet - <sk***@pobox.com> > http://www.pobox.com/~skeet > If replying to the group, please do not mail me too > > Just to clarify - I don't think DataSets naturally have thread affinity Yes this is technically correct. But since a dataset is usually tightly coupled to a view (UI piece) or may contain embedded UI objects then the issues arise. I should have been more accurate with my post. -- Show quoteHide quoteRegards, Alvin Bruney [MVP ASP.NET] [Shameless Author plug] The Microsoft Office Web Components Black Book with .NET Now Available @ http://www.lulu.com/owc ---------------------------------------------------------- "Jon Skeet [C# MVP]" <sk***@pobox.com> wrote in message news:MPG.1c73cb2a501d104698bd05@msnews.microsoft.com... > <"Alvin Bruney [MVP]" <vapor at steaming post office>> wrote: >> This is not a deadlock problem. It's likely a performance issue or an >> unhandled exception. >> The dataaset has thread affinity to the main thread and its also tied to >> the >> dataview object so you need to correctly marshal your update calls using >> invoke. > > Just to clarify - I don't think DataSets naturally have thread affinity > - it's when modifying them makes a UI do something that you have > problems. If you can unbind all the controls from the DataSet, make the > modifications, then put the bindings in again, I think that's fine. > (Alternatively, have a "working" DataSet and a "display" DataSet, and > when all the work has been done, make all the changes again in the > display version.) > > That's the way I understand it, but I may be wrong, in which case I > definitely want to know! > > -- > Jon Skeet - <sk***@pobox.com> > http://www.pobox.com/~skeet > If replying to the group, please do not mail me too
Other interesting topics
MSDN Exception Documentation
PropertyGrid sees only public properties Killing a thread started with delegate.BeginInvoke() More than one user Service may run within the same process Capturing unhandled exceptions Error Spawning Process from ASP.NET DataAdapter & SQLClient http/1.1 500 C# Pocket PC and .NET framework Threading and locked objects |
|||||||||||||||||||||||