I need to know where the taskbar is in my C#, WinForms app. I tried googling as well as searching the MSDN for something useful but nothing came up apart from that: http://msdn.microsoft.com/en-us/library/bb787949(VS.85).aspx[^] and I don't know what's the easiest way insert WinAPI code into a C# application. Or perhaps there's a better way? TIA, Greg
Jergosh
Posts
-
Locating Windows taskbar -
Threading issues when updating GUIS. Senthil Kumar wrote:
I've seen the exception thrown when you are calling BeginInvoke on a control that has been instantiated but has not yet become visible. .NET 2.0 apparently creates the backing Win32 handle lazily, when the control is about to become visible for the first time, and if you happen to call Invoke/BeginInvoke before it, it fails with that error.
This sounds very promising as the controls are indeed hidden -- do you know if this bug applies to .NET 3.5? Cheers, Greg
-
Threading issues when updating GUIHello, First of all, I do realise that the following description is incomplete and it is probably impossible to deduce the exact causes of the problem from it -- the code I'm working on is simply too long to post here in full. I would, however, be very grateful for any hints on how to debug it, or pointers to useful resources on the subject. Here's what I'm struggling with: I'm working on an RSS aggregator in C#. As the network functions are blocking, I use a separate thread for updating the feed subscriptions. The update function generates events which are then caught by each notification 'subsystem' (popup notifiers, tray icon and context menu for now). Realising that UI controls have to be updated from the thread they were created in, I added appropriate InvokeRequired clauses everywhere an event cause the UI to update -- as described in MSDN help. The manual suggests that this should solve the problem but despite that the program crashes frequently. I get the following exception:
Cross-thread operation not valid: Control '' accessed from a thread other than the thread it was created on.
The error occurs when I click on the tray icon just after the feeds have been updated, presumably when the events are still propagating (new items are individually added to the context menu, in the tests I'm using there can be up to about 150 of them). I also looked through a more extensive guide on the subject of threads in general 'Multi-threading in .NET: Introduction and suggestions' (http://www.yoda.arachsys.com/csharp/threads/) but nothing useful came up. Here's an example of event handler (taken from the tray icon context menu class):private delegate void subscriptions_FeedsUpdatedCallback(object sender, FeedsUpdatedArgs e); void subscriptions_FeedsUpdated(object sender, FeedsUpdatedArgs e) { if (this.InvokeRequired) { var d = new subscriptions_FeedsUpdatedCallback(subscriptions_FeedsUpdated); this.BeginInvoke(d, new object[] { sender, e }); } else { HideInfoItem(); // hide the menu entry which displays status information ('Updating...' / 'Connection error') foreach (var menu in FeedMenus) // show submenus for each RSS feed menu.Visible = true; foreach (Subscription feed in subscriptions.Channels) { ToolStripMenuItem menuItem = (ToolStripMenuItem)(this.Items.Find(feed.Name, false))[0]; foreach (Rss.RssItem newitem in feed.NewItems) menu
-
Updating Winforms and multi-threadingLuc Pattyn wrote:
There are basically two ways to do that: 1. the Control.InvokeRequired/Invoke pattern 2. otherwise passing sufficient data to the GUI thread and have it access the Controls (e.g. prepare a collection with new data, and have it processed by a Windows.Forms.Timer, which always ticks on GUI thread!
Most helpful, many thanks :-)
-
Updating Winforms and multi-threadingled mike wrote:
What about Object Oriented Programming and/or Design Patterns, are you new to those as well? What is your background?
I have experience with C, C++ and Python as well as have completed misc university courses (algorithms and data structures etc) but I don't see how that's relevant.
led mike wrote:
Why is that a trick? It's an implementation of inter-thread communications, do you know of some way to communicate between threads that doesn't involve communicating between threads?
I'd say it's less standard than just acquiring lock, doing whatever we like with the object and then releasing it. Less convenient as well if I want, say, clear a menu and populate it with dynamic content as I have to write several helper methods. Apart from that, replacing menuItem.DropDownItems.Clear(); with self-made ClearDropDownMenu(menuItem) isn't particularly object-oriented (or at least doesn't look as if it was). Could we please get back to my initial question?
modified on Thursday, March 6, 2008 3:15 PM
-
Updating Winforms and multi-threadingIs there any other way of updating forms in a thread safe way apart from the delegate/InvokeRequired trick? I'm working on an app (RSS Reader) which has a separate thread for checking if new items appeared and updating context menus accordingly, can I acquire some sort of lock to a control or do I have to create UpdateContextMenuItem(ToolStripMenuItem menuitem, ToolStripItem subitem)-esque methods for each and every action that I may need to perform? I'm new to C#/.NET, and despite initial bias I was quite impressed how clean and well-designed it is, until now. TIA, Greg