Hi:
I am writing a WinForm app that contains a DataGrid control and a StatusBar
control. My goal is to update the status bar using events from a separate
class, as well as some other simple things.
The method I am writing queries a large dataset. As part of my feedback to
the user, I am updating the status bar when the connection is made and the
dataset is actually retrieved. The dataset retrieval method I have placed on
a separate thread so that the status bar updates can be viewed by the user.
Everything works except for the actual binding of my dataset to the grid
control. when I attempt to bind my dataset, i get an error along the lines
of "cannot make control on parent thread of another control" or something to
that effect (I'm sorry, I dont have the actual text handy, and the query
takes a while so forgive the paraphrasing.). I am new to writing.NET
threading code, and would prefer to learn in this instance how it works and
how I broke it rather than copy and paste code, so can anyone please take a
sec and view below and tell me what I am missing? Some of the code I took
from the MSDN's Threading tutorial.
private void mnuGetDocuments_Click(object sender, System.EventArgs e)
{
if (MessageBox.Show(this, "Retrieve list of documents waiting for
printing?", "Confirm Queue Retrieval",
MessageBoxButtons.OKCancel,MessageBoxIcon.Question ) == DialogResult.OK)
{
// my events, QueueDocs is object outside of function scope.
QueueDocs.ConnectionEstablished += new
ConnectionMadeHandler(UpdateStatusOnConnection);
QueueDocs.DatasetReceived += new
DatasetReceivedHandler(UpdateStatusOnDataset);
this.sbOperationStatus.Text = "Retrieving queues... 0% complete";
// instance our new thread
Thread objThread = new Thread(new ThreadStart(this.GetDocuments));
objThread.Start();
while (!objThread.IsAlive)
{
Thread.Sleep(1);
objThread.Abort();
objThread.Join();
}
}
}
private void GetDocuments()
{
DataSet dsLocal = QueueDocs.RetrievePrintQueues();
// breaks here, on binding.
this.dgQueueDocuments.DataSource = dsLocal.Tables[0].DefaultView;
}
Thank you,
Elliot Rodriguez 3 2359
Elliot,
The reason it does not work is that you are trying to update the UI on a
thread that doesn't have the message loop for the UI. If you want to set
the data source on the datagrid (or do any other sort of updates), then you
have to create a delegate and pass it to the Invoke method on the datagrid,
and it will invoke the method, like so:
// The delegate to call the method to set the data source.
private delegate void SetDataSourceCallback(DataView view);
// The method that sets the data source.
private void SetDataSource(DataView view)
{
// Set the data source.
dgQueueDocuments.DataSource = view;
}
// This code is called in the thread.
// Your comment:
// breaks here, on binding.
dgQueueDocuments.Invoke(new SetDataSourceCallback(SetDataSource,
new object[]{dsLocal.Tables[0].DefaultView});
You will have to do this for any UI operation you want to perform from
another thread, including your update of the status bar.
A few other things. I don't understand the purpose of this code:
while (!objThread.IsAlive)
{
Thread.Sleep(1);
objThread.Abort();
objThread.Join();
}
Your thread should always be alive, and if you were waiting for the
process to kick off, you would end up sleeping for a second then aborting
it. It doesn't make sense. If you want to wait for the thread to kick off,
then use a ManualResetEvent and wait on it, and set it in the first line of
your method that is called on the new thread.
Also, if you bind to dsLocal.Tables[0], the data grid will automatically
bind to the DefaultView property on that table, it never binds to the table
directly.
Hope this helps.
--
- Nicholas Paldino [.NET/C# MVP]
- mv*@spam.guard.caspershouse.com
"Elliot Rodriguez" <el*************@geemail.com> wrote in message
news:e7**************@TK2MSFTNGP12.phx.gbl... Hi:
I am writing a WinForm app that contains a DataGrid control and a StatusBar control. My goal is to update the status bar using events from a separate class, as well as some other simple things.
The method I am writing queries a large dataset. As part of my feedback to the user, I am updating the status bar when the connection is made and the dataset is actually retrieved. The dataset retrieval method I have placed on a separate thread so that the status bar updates can be viewed by the user.
Everything works except for the actual binding of my dataset to the grid control. when I attempt to bind my dataset, i get an error along the lines of "cannot make control on parent thread of another control" or something to that effect (I'm sorry, I dont have the actual text handy, and the query takes a while so forgive the paraphrasing.). I am new to writing.NET threading code, and would prefer to learn in this instance how it works and how I broke it rather than copy and paste code, so can anyone please take a sec and view below and tell me what I am missing? Some of the code I took from the MSDN's Threading tutorial.
private void mnuGetDocuments_Click(object sender, System.EventArgs e)
{
if (MessageBox.Show(this, "Retrieve list of documents waiting for printing?", "Confirm Queue Retrieval", MessageBoxButtons.OKCancel,MessageBoxIcon.Question ) == DialogResult.OK)
{
// my events, QueueDocs is object outside of function scope.
QueueDocs.ConnectionEstablished += new ConnectionMadeHandler(UpdateStatusOnConnection);
QueueDocs.DatasetReceived += new DatasetReceivedHandler(UpdateStatusOnDataset);
this.sbOperationStatus.Text = "Retrieving queues... 0% complete";
// instance our new thread
Thread objThread = new Thread(new ThreadStart(this.GetDocuments));
objThread.Start();
while (!objThread.IsAlive)
{
Thread.Sleep(1);
objThread.Abort();
objThread.Join();
}
}
} private void GetDocuments()
{
DataSet dsLocal = QueueDocs.RetrievePrintQueues();
// breaks here, on binding.
this.dgQueueDocuments.DataSource = dsLocal.Tables[0].DefaultView;
} Thank you, Elliot Rodriguez
Nicholas:
Thanks for your reply.
In response to:
while (!objThread.IsAlive)
{
Thread.Sleep(1);
objThread.Abort();
objThread.Join();
}
Well, this was part of the threading tutorial I found in the MSDN. To me it
seemed it was a requirement for implementation. If youre suggesting its not
needed, then I should certainly remove it.
However, I understood this snippet to be the code that kills the thread. I
could be wrong of course.
Again, many thanks.
Elliot Rodriguez
"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.com> wrote in
message news:ea**************@TK2MSFTNGP15.phx.gbl... Elliot,
The reason it does not work is that you are trying to update the UI on a thread that doesn't have the message loop for the UI. If you want to set the data source on the datagrid (or do any other sort of updates), then you have to create a delegate and pass it to the Invoke method on the datagrid, and it will invoke the method, like so:
// The delegate to call the method to set the data source. private delegate void SetDataSourceCallback(DataView view);
// The method that sets the data source. private void SetDataSource(DataView view) { // Set the data source. dgQueueDocuments.DataSource = view; }
// This code is called in the thread. // Your comment: // breaks here, on binding. dgQueueDocuments.Invoke(new SetDataSourceCallback(SetDataSource, new object[]{dsLocal.Tables[0].DefaultView});
You will have to do this for any UI operation you want to perform from another thread, including your update of the status bar.
A few other things. I don't understand the purpose of this code:
while (!objThread.IsAlive) { Thread.Sleep(1); objThread.Abort(); objThread.Join(); }
Your thread should always be alive, and if you were waiting for the process to kick off, you would end up sleeping for a second then aborting it. It doesn't make sense. If you want to wait for the thread to kick off, then use a ManualResetEvent and wait on it, and set it in the first line of your method that is called on the new thread.
Also, if you bind to dsLocal.Tables[0], the data grid will automatically bind to the DefaultView property on that table, it never binds to the table directly.
Hope this helps.
-- - Nicholas Paldino [.NET/C# MVP] - mv*@spam.guard.caspershouse.com
"Elliot Rodriguez" <el*************@geemail.com> wrote in message news:e7**************@TK2MSFTNGP12.phx.gbl... Hi:
I am writing a WinForm app that contains a DataGrid control and a StatusBar control. My goal is to update the status bar using events from a separate class, as well as some other simple things.
The method I am writing queries a large dataset. As part of my feedback to the user, I am updating the status bar when the connection is made and the dataset is actually retrieved. The dataset retrieval method I have placed on a separate thread so that the status bar updates can be viewed by the user.
Everything works except for the actual binding of my dataset to the grid control. when I attempt to bind my dataset, i get an error along the lines of "cannot make control on parent thread of another control" or something to that effect (I'm sorry, I dont have the actual text handy, and the query takes a while so forgive the paraphrasing.). I am new to writing.NET threading code, and would prefer to learn in this instance how it works and how I broke it rather than copy and paste code, so can anyone please take a sec and view below and tell me what I am missing? Some of the code I took from the MSDN's Threading tutorial.
private void mnuGetDocuments_Click(object sender, System.EventArgs e)
{
if (MessageBox.Show(this, "Retrieve list of documents waiting for printing?", "Confirm Queue Retrieval", MessageBoxButtons.OKCancel,MessageBoxIcon.Question ) == DialogResult.OK)
{
// my events, QueueDocs is object outside of function scope.
QueueDocs.ConnectionEstablished += new ConnectionMadeHandler(UpdateStatusOnConnection);
QueueDocs.DatasetReceived += new DatasetReceivedHandler(UpdateStatusOnDataset);
this.sbOperationStatus.Text = "Retrieving queues... 0% complete";
// instance our new thread
Thread objThread = new Thread(new ThreadStart(this.GetDocuments));
objThread.Start();
while (!objThread.IsAlive)
{
Thread.Sleep(1);
objThread.Abort();
objThread.Join();
}
}
} private void GetDocuments()
{
DataSet dsLocal = QueueDocs.RetrievePrintQueues();
// breaks here, on binding.
this.dgQueueDocuments.DataSource = dsLocal.Tables[0].DefaultView;
} Thank you, Elliot Rodriguez
Nicholas:
I am having trouble implementing the code you posted.
I've been checking out Google and it appears that it should work, but I am
not sure why it isnt.
If I use your code as is, I get the error "Method(method name) referenced
without parentheses".
Thinking this was just an oversight, I added the parens, at which point I
thought I should pass an argument (since the method expects one), and that
breaks as well "Method name expected".
Frankly I am still very fuzzy on how threading works in .NET, so I am not
sure what to do here.
Thanks again,
Elliot
"Nicholas Paldino [.NET/C# MVP]" <mv*@spam.guard.caspershouse.com> wrote in
message news:ea**************@TK2MSFTNGP15.phx.gbl... Elliot,
The reason it does not work is that you are trying to update the UI on a thread that doesn't have the message loop for the UI. If you want to set the data source on the datagrid (or do any other sort of updates), then you have to create a delegate and pass it to the Invoke method on the datagrid, and it will invoke the method, like so:
// The delegate to call the method to set the data source. private delegate void SetDataSourceCallback(DataView view);
// The method that sets the data source. private void SetDataSource(DataView view) { // Set the data source. dgQueueDocuments.DataSource = view; }
// This code is called in the thread. // Your comment: // breaks here, on binding. dgQueueDocuments.Invoke(new SetDataSourceCallback(SetDataSource, new object[]{dsLocal.Tables[0].DefaultView});
You will have to do this for any UI operation you want to perform from another thread, including your update of the status bar.
A few other things. I don't understand the purpose of this code:
while (!objThread.IsAlive) { Thread.Sleep(1); objThread.Abort(); objThread.Join(); }
Your thread should always be alive, and if you were waiting for the process to kick off, you would end up sleeping for a second then aborting it. It doesn't make sense. If you want to wait for the thread to kick off, then use a ManualResetEvent and wait on it, and set it in the first line of your method that is called on the new thread.
Also, if you bind to dsLocal.Tables[0], the data grid will automatically bind to the DefaultView property on that table, it never binds to the table directly.
Hope this helps.
-- - Nicholas Paldino [.NET/C# MVP] - mv*@spam.guard.caspershouse.com
"Elliot Rodriguez" <el*************@geemail.com> wrote in message news:e7**************@TK2MSFTNGP12.phx.gbl... Hi:
I am writing a WinForm app that contains a DataGrid control and a StatusBar control. My goal is to update the status bar using events from a separate class, as well as some other simple things.
The method I am writing queries a large dataset. As part of my feedback to the user, I am updating the status bar when the connection is made and the dataset is actually retrieved. The dataset retrieval method I have placed on a separate thread so that the status bar updates can be viewed by the user.
Everything works except for the actual binding of my dataset to the grid control. when I attempt to bind my dataset, i get an error along the lines of "cannot make control on parent thread of another control" or something to that effect (I'm sorry, I dont have the actual text handy, and the query takes a while so forgive the paraphrasing.). I am new to writing.NET threading code, and would prefer to learn in this instance how it works and how I broke it rather than copy and paste code, so can anyone please take a sec and view below and tell me what I am missing? Some of the code I took from the MSDN's Threading tutorial.
private void mnuGetDocuments_Click(object sender, System.EventArgs e)
{
if (MessageBox.Show(this, "Retrieve list of documents waiting for printing?", "Confirm Queue Retrieval", MessageBoxButtons.OKCancel,MessageBoxIcon.Question ) == DialogResult.OK)
{
// my events, QueueDocs is object outside of function scope.
QueueDocs.ConnectionEstablished += new ConnectionMadeHandler(UpdateStatusOnConnection);
QueueDocs.DatasetReceived += new DatasetReceivedHandler(UpdateStatusOnDataset);
this.sbOperationStatus.Text = "Retrieving queues... 0% complete";
// instance our new thread
Thread objThread = new Thread(new ThreadStart(this.GetDocuments));
objThread.Start();
while (!objThread.IsAlive)
{
Thread.Sleep(1);
objThread.Abort();
objThread.Join();
}
}
} private void GetDocuments()
{
DataSet dsLocal = QueueDocs.RetrievePrintQueues();
// breaks here, on binding.
this.dgQueueDocuments.DataSource = dsLocal.Tables[0].DefaultView;
} Thank you, Elliot Rodriguez
This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics
by: GrantS |
last post by:
I need urgent help. Done OK for a newbie getting automation of Windows
Messenger into a Winform C# app but have three problems that I
urgently need pointers to. Point 1 and 2 are the same issue, I...
|
by: Eric |
last post by:
I'm looking at this page in the MSDN right here:
ms-help://MS.MSDNQTR.2003FEB.1033/cpref/html/frlrfsystemcollectionsarraylist
classsynchronizedtopic2.htm
(or online here:...
|
by: Brian |
last post by:
Thanks.
|
by: Z D |
last post by:
Hello,
I'm having a strange problem that is probably due to my lack of
understanding of how threading & COM Interop works in a WinForms.NET
application.
Here's the situation:
I have a 3rd...
|
by: Sgt. Sausage |
last post by:
Problem. Work-around. No issues, just looking to see
if I'm the only one that's seen this.
I just lost 3 hours (shoulda found it sooner) to the
InvokeRequired on a form being somewhat...
|
by: Jim H |
last post by:
I have work being done in worker threads and I trigger an event, that gui
objects have subscribed to, when the work is complete. Will that event
handler code be executed in the ui thread or the...
|
by: Anthony Nystrom |
last post by:
What is the correct way to stop a thread? abort? sleep? Will it start up
again... Just curious... If the thread is enabling a form, if the form is
disposed is the thread as well?
Thanks,
...
|
by: sklett |
last post by:
In the past I've had problems with using threads and getting all kinds of
weird bugs.
I've been reading over Jon Skeet's GREAT website about threading and have
tried to apply some of what I...
|
by: Richard MSL |
last post by:
I have a C# application that works, with a main menu where the user can
choose different options that run, and then return to the menu. I want to
change it so that the user can starting running an...
|
by: BarryA |
last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
|
by: nemocccc |
last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
|
by: Sonnysonu |
last post by:
This is the data of csv file
1 2 3
1 2 3
1 2 3
1 2 3
2 3
2 3
3
the lengths should be different i have to store the data by column-wise with in the specific length.
suppose the i have to...
|
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...
|
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,...
|
by: Hystou |
last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers,...
|
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...
|
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...
| |