Re: Simple Threading Problem with WinForm
- From: "Nicholas Paldino [.NET/C# MVP]" <mvp@xxxxxxxxxxxxxxxxxxxxxxxxxxx>
- Date: Tue, 14 Jun 2005 11:44:41 -0400
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]
- mvp@xxxxxxxxxxxxxxxxxxxxxxxxxxx
"Elliot Rodriguez" <elliotrodriguez@xxxxxxxxxxx> wrote in message
news:e7wFYYPcFHA.2420@xxxxxxxxxxxxxxxxxxxxxxx
> 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
>
>
.
- Follow-Ups:
- Re: Simple Threading Problem with WinForm
- From: Elliot Rodriguez
- Re: Simple Threading Problem with WinForm
- From: Elliot Rodriguez
- Re: Simple Threading Problem with WinForm
- References:
- Simple Threading Problem with WinForm
- From: Elliot Rodriguez
- Simple Threading Problem with WinForm
- Prev by Date: Problem converting byte[] to string
- Next by Date: Static Functions in a Multi Threaded App
- Previous by thread: Simple Threading Problem with WinForm
- Next by thread: Re: Simple Threading Problem with WinForm
- Index(es):