473,406 Members | 2,387 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,406 software developers and data experts.

Multithreading a databound app?

I am looking for a resource to learn how to do multithreading in a data
bound app. So far, I have figured out that I can't update a databound object
on a worker thread, because that triggers a cross-thread call to the UI
control that it is bound to.

I have created a simple demo to explore the problem. The demo has a
dataGridView control, a bindingSource control, a backgroundWorker control
and a Go button. The grid is bound via the BindingSource to WidgetList,
which is a llist of WidgetItem objects derived from BindingList<T>.
WidgetList has one method, PopulateList(), which simply adds 100 WidgetItems
to itself, very slowly.

At run time, the WidgetList is instantiated and bound to the bindingSource
control in the FormLoad method. The backgroundWorker's DoWork event handler
calls the WidgetList's PopulateList() method.

I had hoped I could populate the list on a worker thread without triggering
a UI control call. I'm getting a cross-thread UI call exception, even when I
suspend binding on the bindingSource and the dataGridView.

The other demos I have downloaded all seem to fudge the issue by creating an
object in the worker thread, then binding it after the thread completes.
That won't work for me, since my production app needs to transform the same
collection in a series of operations.

Can a databound object be updated on a worker thread? If so, how is it done?
Has anyone seen any good articles that discuss the issue? Thanks.

--
David Veeneman
Foresight Systems
Aug 1 '06 #1
6 5658
David,

No, it can't be done. You should probably unbind the object itself,
perform your operation, and then bind the object back.

Hop ethis helps.

--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com

"David Veeneman" <da****@nospam.com (domain is my last name)wrote in
message news:%2****************@TK2MSFTNGP03.phx.gbl...
>I am looking for a resource to learn how to do multithreading in a data
bound app. So far, I have figured out that I can't update a databound
object on a worker thread, because that triggers a cross-thread call to the
UI control that it is bound to.

I have created a simple demo to explore the problem. The demo has a
dataGridView control, a bindingSource control, a backgroundWorker control
and a Go button. The grid is bound via the BindingSource to WidgetList,
which is a llist of WidgetItem objects derived from BindingList<T>.
WidgetList has one method, PopulateList(), which simply adds 100
WidgetItems to itself, very slowly.

At run time, the WidgetList is instantiated and bound to the bindingSource
control in the FormLoad method. The backgroundWorker's DoWork event
handler calls the WidgetList's PopulateList() method.

I had hoped I could populate the list on a worker thread without
triggering a UI control call. I'm getting a cross-thread UI call
exception, even when I suspend binding on the bindingSource and the
dataGridView.

The other demos I have downloaded all seem to fudge the issue by creating
an object in the worker thread, then binding it after the thread
completes. That won't work for me, since my production app needs to
transform the same collection in a series of operations.

Can a databound object be updated on a worker thread? If so, how is it
done? Has anyone seen any good articles that discuss the issue? Thanks.

--
David Veeneman
Foresight Systems

Aug 1 '06 #2
See my post a few days ago; in the end I wrote a ThreadedBinding
(equiv. to Binding) to help with this issue; following link may work:

http://groups.google.com/group/micro...078656d6f1ee1f

Or: Tues, Jul 25 2006 9:31 am, by myself, titled "Threaded Bindings
don't update"

Hope it helps,

Marc

Aug 1 '06 #3
Thanks--but how do I unbind the object? I've tried setting the DataSource of
the bindingSource and the dataGridView to null, but I'm still getting the
same illegal cross-thread call exception on the DGV.

Thanks agsin for your help.

--
David Veeneman
Foresight Systems
Aug 1 '06 #4
I found my answer--see below. Thanks again for your help.
Aug 1 '06 #5
I found my answer. Thanks to those who responded to my original question!

As Nicholas Paladino pointed out, you have to disconnect a control from a
bound object before you update the object on a worker thread. Then update
it, and when the worker thread completes, rebind the resulting object.

In my demo project, I am using a dataGridView control bound to a
bindingSource control. The binding source control is bound to a WidgetList.
Here's how I fixed my code:

(1) I threw out the WidgetList member variable. Instead, I created it as a
local variable in the FormLoad event handler and set it as the
bindingSource.DataSource.

private void this_Load(object sender, EventArgs e)
{
WidgetList widgetList = new WidgetList();
widgetListBindingSource.DataSource = widgetList;
}

(2) In the button handler that triggers the background worker, I get the
WidgetList from the bindinmgSource, then clear bindingSource.DataSource. I
also show a label and progress bar to show the progress of the operation. I
pass the WidgetList to the worker thread as the argument to
RunWorkerAsync():

private void toolBarButtonGo_Click(object sender, EventArgs e)
{
statusStripLabel1.Visible = true;
statusStripProgressBar1.Visible = true;
WidgetList widgetList = (WidgetList)widgetListBindingSource.DataSource;
widgetListBindingSource.DataSource = null;
backgroundWorker1.RunWorkerAsync(widgetList);
}

(3) The backgroundWorker.DoWork event fires. I get the WidgetList from the
event args and pass it to my worker method. The worker method returns the
loaded WidgetList, which I put into the event args:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
// Call method to be run on worker thread
WidgetList argumentList = (WidgetList)e.Argument;
WidgetList resultList = this.PopulateList(argumentList);
e.Result = resultList;
}

Here is the worker method from my demo:

private WidgetList PopulateList(WidgetList widgetList)
{
for (int i = 0; i < 100; i++)
{
// Add new widget to the list
WidgetItem widget = new WidgetItem(i);
widgetList.Add(widget);

// Pause to simulate slow process
Thread.Sleep(100);

// Report progress
backgroundWorker1.ReportProgress(i);
}
return widgetList;
}

(4) When the worker thread completes, I get the WidgetList from the
backgroundWorker.RunWorkerCompleted event args and re-bind the binding
source to it. I also hide the progress bar and label:

private void backgroundWorker1_RunWorkerCompleted(object sender,
RunWorkerCompletedEventArgs e)
{
WidgetList widgetList = (WidgetList)e.Result;
widgetListBindingSource.DataSource = widgetList;
statusStripLabel1.Visible = false;
statusStripProgressBar1.Visible = false;
}

(5) While the operation is in progress, my worker method periodically
instructs the background worker to report its progress (see worker method
above).

(6) The backgroundWorker.ProgressChanged event fires each time
backgroundWorkerReportProgress() is called. It simply updates the progress
bar:

private void backgroundWorker1_ProgressChanged(object sender,
ProgressChangedEventArgs e)
{
statusStripProgressBar1.Value = e.ProgressPercentage;
}

The overall result is that I have preserved the identity of my WidgetList
and updated it on a worker thread, without making any significant changes to
my data binding scheme.

--
David Veeneman
Foresight Systems


Aug 1 '06 #6
An update--I subsequently discovered that SuspendBinding() and
ResumeBinding() do eliminate the cross-thread control call problem in my
original message. You don't need to set the DataSource to null.

The trick is to call SuspendBinding() before calling
BackgroundWorker.RunWorkerAsync(), and to call ResumeBinding() after the
asynchronous process completes-- in the RunWorkerCompleted() event handler
or later. Here is how I did the second step:

// Re-bind binding source control to updated widget list
widgetListBindingSource.DataSource = newWidgetList;
widgetListBindingSource.ResumeBinding();

The newWidgetList object was returned to me in the
RunWorkerCompletedEventArgs.Result property:

WidgetList widgetList = (WidgetList)e.Result;
--
David Veeneman
Foresight Systems

Aug 3 '06 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

47
by: mihai | last post by:
What does the standard say about those two? Is any assurance that the use of STL is thread safe? Have a nice day, Mihai.
16
by: Robert Zurer | last post by:
Can anyone suggest the best book or part of a book on this subject. I'm looking for an in-depth treatment with examples in C# TIA Robert Zurer robert@zurer.com
5
by: sarge | last post by:
I would like to know how to perform simple multithreading. I had created a simple form to test out if I was multithreading properly, but got buggy results. Sometime the whole thig would lock up...
9
by: tommy | last post by:
hi, i have found a example for multithreading and asp.net http://www.fawcette.com/vsm/2002_11/magazine/features/chester/ i want to speed up my website ... if my website is starting, they...
2
by: Rich | last post by:
Hello, I have set up a multithreading routine in a Test VB.net proj, and it appears to be working OK in debug mode and I am not using synchronization. Multithreading is a new thing for me, and...
55
by: Sam | last post by:
Hi, I have a serious issue using multithreading. A sample application showing my issue can be downloaded here: http://graphicsxp.free.fr/WindowsApplication11.zip The problem is that I need to...
5
by: clickon | last post by:
This is driving me nuts, it is such a simply thing to do but i cannot for the life of me work out how you are suposed to do it. I want to update the data in DropDownListB based on what is...
5
by: sandy82 | last post by:
Whats actuallly multithreading is ... and how threading and multithreading differ . Can any1 guide how multithreading is used on the Web .. i mean a practical scenario in which u use...
7
by: Ray | last post by:
Hello, Greetings! I'm looking for a solid C++ multithreading book. Can you recommend one? I don't think I've seen a multithreading C++ book that everybody thinks is good (like Effective C++ or...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.