Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

[Repost] Thread Questions

1 view
Skip to first unread message

Mythran

unread,
May 24, 2005, 4:23:03 PM5/24/05
to
Been 11 days since I posted this and 0 replies (although, in OE, it looks
like there was 1 but it's just another post with the same subject as
before):

Part #1:
I have a Thread, MainThread, and a child thread that is started in the
MainThread called ChildThread.

I have a DataSet created in the MainThread in which needs to be passed to
the ChildThread. The ChildThread needs to update the DataSet with new data.
The MainThread, after the ChildThread is finished, needs to continue on it's
merry way updating the DataSet.


Part #2:
I have MainThread and ChildThread ... in ChildThread, I need to create a
DataSet and/or a DataTable. The DataSet then needs to be passed to the
MainThread and then bound to either a DataGrid or Crystal Report...

I have tried both of the above questions but seem to get the same result
every time. Something about can't reference an object created on a
different thread. It was some time ago, and I just remembered about it and
am now curious. I can try setting up a project and duplicating my problems
again if need be...but hopefully there is a short/semi-short method that can
be described using pseudo/semi-pseudo code...

The problem is for C# or VB.Net, either will solve for the other...as it
should be, if any examples/code is given.

Thanks!

Mythran

Some Guy

unread,
May 24, 2005, 10:09:56 PM5/24/05
to
This is one way you can do it. Use a ArrayList and then lock it before you
use it. Play around with it.

Dim al as New ArrayList

Thread #1
'--- Lock ArrayList and add
Monitor.Enter(al.SyncRoot)
al.Add(myDataset)
Monitor.Exit(al.SyncRoot)

In Thread #2
Monitor.Enter(al.SyncRoot)
dim obj as Object = al.Item(0) '-- May have to cast
al.Remove(0)
'-- Do whatever
Monitor.Exit(al.SyncRoot)


"Mythran" <kip_p...@hotmail.comREMOVETRAIL> wrote in message
news:uXjQk5JY...@TK2MSFTNGP15.phx.gbl...

Cor Ligthert

unread,
May 25, 2005, 3:52:56 AM5/25/05
to
Mythran,

> Part #1:
> I have a Thread, MainThread, and a child thread that is started in the
> MainThread called ChildThread.
>
> I have a DataSet created in the MainThread in which needs to be passed to
> the ChildThread. The ChildThread needs to update the DataSet with new
> data.
> The MainThread, after the ChildThread is finished, needs to continue on
> it's
> merry way updating the DataSet.
>

Question in this is.

What does the mainthread meanwhile

Do you mean with update a dataset, (re)fill a dataset or update a database
with a dataset?


>
>
> Part #2:
> I have MainThread and ChildThread ... in ChildThread, I need to create a
> DataSet and/or a DataTable. The DataSet then needs to be passed to the
> MainThread and then bound to either a DataGrid or Crystal Report...
>

Here is the simple solution that you have to set the dataset in a global
place in your solution. That is all.

However I am very curious what the reason is from such a solution. I can
think about somehting. However the process of filling and updating with a
dataset is a process very dependent from the concurrency. When I think what
you want to do, than I see only problems, so enlighten me with what you are
up to.

Cor


Mythran

unread,
May 25, 2005, 11:48:20 AM5/25/05
to
>>
>> Part #2:
>> I have MainThread and ChildThread ... in ChildThread, I need to create a
>> DataSet and/or a DataTable. The DataSet then needs to be passed to the
>> MainThread and then bound to either a DataGrid or Crystal Report...
>>
> Here is the simple solution that you have to set the dataset in a global
> place in your solution. That is all.
>
> However I am very curious what the reason is from such a solution. I can
> think about somehting. However the process of filling and updating with a
> dataset is a process very dependent from the concurrency. When I think
> what you want to do, than I see only problems, so enlighten me with what
> you are up to.
>
> Cor
>


So, you are saying to create a global variable somewhere in my UI project.
And access this variable (DataSet) from any and all threads that need it? I
never like the idea of global variables, but that's just me. Is there any
other way?

Basically, what I have needed before and what spawned this question
originally was a situation like the following:

MainForm:
User presses a button to view a report (Crystal Report). The button
event calls a method in a class. This method creates a child thread that
will retrieve the data from the database and store it into a DataSet
(typed). The DataSet then needs to be attached to the Crystal Report Viewer
that is on the Windows Form (MainForm). Whenever I try to create the
DataSet in the child thread, or when I create the DataSet in the parent
thread and fill it in the child thread, I get an exception when I try to
load the viewer with the data in the DataSet. I can't remember the actual
exception, so if it is needed to help with this, I can reproduce the
exception and display a SHORT BUT COMPLETE PROJECT (that's for you Mr. Skeet
;p ) to help show you my problem.

Anywho, hope this sheds some more light on what I'm trying to accomplish.
If you have any more questions that I need to answer first, lemme know ..

Thanks, btw, been asking this question for a long time and never even have
received a reply before :)

Mythran

Cor Ligthert

unread,
May 25, 2005, 1:22:56 PM5/25/05
to
Mythran,

I don't like to set things global either

What I do, is this
Class my
public event ready
Private mydataset
Public sub new(byval ds as dataset)
mydataset = ds
end sub
Public sub myproc
at the end raiseevent ready
end sub

dim mymy as new my(mydataset) 'the dataset is in the main thread
AddHandler my.Ready, AddressOf myReadyEvent
ThreadMy = New System.Threading.Thread(AddressOf mymy.myproc)
ThreadMy.Name = "My"
ThreadMy.Start.Start()

I have to go, I hope this is clear,

Think as well twice why you want to use threading here. Threading cost in
your process surely extra processing time, and you will loose that as well
in througput time because of the fact that you have no seperated not
dependable processes running at the same time. They are all sequential.

I hope this helps,

Cor


"Mythran" <kip_p...@hotmail.comREMOVETRAIL> schreef in bericht
news:uFxatEUY...@tk2msftngp13.phx.gbl...

Mythran

unread,
May 25, 2005, 1:50:48 PM5/25/05
to

"Cor Ligthert" <notmyfi...@planet.nl> wrote in message
news:u$TPy5UYF...@TK2MSFTNGP09.phx.gbl...

> Mythran,
>
> I don't like to set things global either
>
> What I do, is this
> Class my
> public event ready
> Private mydataset
> Public sub new(byval ds as dataset)
> mydataset = ds
> end sub
> Public sub myproc
> at the end raiseevent ready
> end sub
>
> dim mymy as new my(mydataset) 'the dataset is in the main thread
> AddHandler my.Ready, AddressOf myReadyEvent
> ThreadMy = New System.Threading.Thread(AddressOf mymy.myproc)
> ThreadMy.Name = "My"
> ThreadMy.Start.Start()
>
> I have to go, I hope this is clear,
>
> Think as well twice why you want to use threading here. Threading cost in
> your process surely extra processing time, and you will loose that as well
> in througput time because of the fact that you have no seperated not
> dependable processes running at the same time. They are all sequential.
>
> I hope this helps,
>
> Cor
>

The reason I am using Threading in this situation is the data retrieval may
take a long time to retrieve and process (a lot of records, the report can
be upwards of 50MB...yes this is a very large report [set of reports]). We
put it in a separate thread so that the user can click on the cancel button
and kill the thread.

There may be other ways...but I am learning threading and find this to be
useful here ;)

I will try your example out and see how it goes.

Mythran

Mythran

unread,
May 25, 2005, 3:13:42 PM5/25/05
to

"Mythran" <kip_p...@hotmail.comREMOVETRAIL> wrote in message
news:%23tbyJJV...@TK2MSFTNGP10.phx.gbl...
[Yes, I am in vb.net group but I started writing this in C# so that is what
I'm posting the code in...sorry]

I tried the above (in C# anyways) and it gives me the following error
message when I bind the DataTable (not DataSet) to a DataGrid (for testing):

"Controls created on one thread cannot be parented to a control on a
different thread."

The way I have it set up is...(off top of head, won't compile...most likely)

form code -
execute method:
DataTable dt = (new DataSet()).Tables.Add("tblSample");
dt.Columns.Add("LastName");
dt.Columns.Add("FirstName");
engine = new ReportEngine(dt);
engine.DataReady += new DataReadyEvent(Engine_DataReady);

ThreadStart threadStart = new ThreadStart(engine.RaiseEvent);
Thread childThread = new Thread(threadStart);
childThread.Name = "Child Thread";
childThread.Start();

Engine_DataReady(DataTable Data):
try {
grdResults.DataSource = Data;
} catch (Exception ex) {
MessageBox.Show(ex.Message);
}

end of form

Namespace code:
public delegate void DataReadyEvent(DataTable Data);

ReportEngine code:

public event DataReadyEvent DataReady;
private DataTable mData;

ReportEngine(DataTable Data) constructor:
mData = Data;

RaiseEvent method:
mData.Rows.Add(new string[] { "Potter", "Kip" });

if (DataReady != null) {
DataReady(mData);
}

end of ReportEngine code.


The exception is raised in the Engine_DataReady event handler where I'm
binding the DataTable to the DataGrid's DataSource property. I have
narrowed it down in the past and believe it's still the same, the DataRow
that was created on the child thread is the problem here. When I step
through to the Engine_DataReady handler, I can do Data.Rows[0]["LastName"]
and it gives me "Potter". If I remove the row from the DataTable and then
continue the program, it binds correctly (but no data, of course).

Hope this is still clear enough. Let me know what you think I should do in
this case please :)

Thanks in advance, again, you are a big help in this.

Mythran

Mythran

unread,
May 25, 2005, 6:49:11 PM5/25/05
to
Got it working. Instead of setting the DataSource of the DataGrid to the
DAtaTable in the event handler, I stored the datatable into a member
variable on the form. Then I wait until the child thread is stopped/done
(Thread.Join()) then bind the DataTable to the DataGrid.

Thanks, btw :)

Mythran

0 new messages