Threading with UI elements - dynamically created controls? | | |
I have a UI that needs a couple of threads to do some significant processing
on a couple of different forms - and while it's at it, update the UI (set
textboxes, fill in listviews). I created a base class for the worker class,
and made up some functions/delegates to handle the invoke stuff for the UI
and that was fine for a prototype. I rewrote this chunk, broke things out
into different classes - but the threading is still the same - and one
specific problem I'm having is this.
Within the worker thread, I do this:
ListViewItem lvwItem = new ListViewItem();
I want to try to do as much work as possible, while leaving a lot of
potential functionality in the worker thread. So I'd like to pre-populate a
ListViewItem - and then do the Invoke to just add that pre-filled
ListViewItem to the listview on the UI.
On that line, I get an error of:
Illegal cross-thread operation: Control 'frmPopup' accessed from a thread
other than the thread it was created on.
Stack trace where the illegal operation occurred was:
at System.Windows.Forms.Control.get_Handle() etc, etc
And it happens right at that line above when I'm trying to create a
ListViewItem programatically. I am assuming that when you create a UI
element programatically, it needs a window handle? If so - how do I get
around this? And I know I've had this work before, the only thing different
is I have this functionality in a seperate class.
Also - I got rid of 100% of the functionality in that thread (commented it
out) - and slowly added lines back in, and this is the only, even remote
reference to a UI element in this chunk of code, and this is the specific
line that throws the exception.
Any ideas??? | | | | re: Threading with UI elements - dynamically created controls?
I don't know how your creating your thread, but it sounds like the error is
in how you pass back the result to the main ( calling ) thread.
So, for example, if you try to add lvwItem to frmPopup in the spawned thread
you might get that error.
If you set up, say, a thread pool, that calls a method that returns
ListViewItem as a result, and then add it to frmPopup control array, that
might be different.
RCS wrote:
[color=blue]
>
> I have a UI that needs a couple of threads to do some significant
> processing on a couple of different forms - and while it's at it, update
> the UI (set textboxes, fill in listviews). I created a base class for the
> worker class, and made up some functions/delegates to handle the invoke
> stuff for the UI and that was fine for a prototype. I rewrote this chunk,
> broke things out into different classes - but the threading is still the
> same - and one specific problem I'm having is this.
>
> Within the worker thread, I do this:
>
> ListViewItem lvwItem = new ListViewItem();
>
> I want to try to do as much work as possible, while leaving a lot of
> potential functionality in the worker thread. So I'd like to pre-populate
> a ListViewItem - and then do the Invoke to just add that pre-filled
> ListViewItem to the listview on the UI.
>
> On that line, I get an error of:
>
> Illegal cross-thread operation: Control 'frmPopup' accessed from a thread
> other than the thread it was created on.
> Stack trace where the illegal operation occurred was:
>
> at System.Windows.Forms.Control.get_Handle() etc, etc
>
> And it happens right at that line above when I'm trying to create a
> ListViewItem programatically. I am assuming that when you create a UI
> element programatically, it needs a window handle? If so - how do I get
> around this? And I know I've had this work before, the only thing
> different is I have this functionality in a seperate class.
>
> Also - I got rid of 100% of the functionality in that thread (commented it
> out) - and slowly added lines back in, and this is the only, even remote
> reference to a UI element in this chunk of code, and this is the specific
> line that throws the exception.
>
> Any ideas???[/color]
--
Texeme http://texeme.com | | | | re: Threading with UI elements - dynamically created controls?
Windows doesn't allow a secondary thread to update any UI elements. You have
to have the original UI thread do that. So what you can do from the
secondary thread is:
if ( InvokeRequired )
{
BeginInvoke(...)
}
// Do the real work here
That part of this, is all good and works fine. There is somewhat of a
detailed class that handles all the UI elements that I'd need to update from
a background thread. But way before I get to that, and to address what
you've asked. From the UI thread I do this to start things off:
System.Threading.ThreadStart objTS = new System.Threading.ThreadStart(
LoadListView1 );
System.Threading.Thread objThread = new System.Threading.Thread( objTS );
objThread.Name = "LoadListView1";
objThread.Start();
Then, within that function, I am immediately doing this:
ListViewItem lvwItem = new ListViewItem();
That is enough to make it fail. So, I'm not actually trying to update any UI
elements on a form, at this point - I'm just programatically creating a UI
element that will be added to one of my forms later.
"Elidel" <im@elidel.l.eh.del> wrote in message
news:rX8Nd.1166$UX3.1062@newsread3.news.pas.earthl ink.net...[color=blue]
>
> I don't know how your creating your thread, but it sounds like the error
> is
> in how you pass back the result to the main ( calling ) thread.
>
> So, for example, if you try to add lvwItem to frmPopup in the spawned
> thread
> you might get that error.
>
> If you set up, say, a thread pool, that calls a method that returns
> ListViewItem as a result, and then add it to frmPopup control array, that
> might be different.
>
> RCS wrote:
>[color=green]
>>
>> I have a UI that needs a couple of threads to do some significant
>> processing on a couple of different forms - and while it's at it, update
>> the UI (set textboxes, fill in listviews). I created a base class for the
>> worker class, and made up some functions/delegates to handle the invoke
>> stuff for the UI and that was fine for a prototype. I rewrote this chunk,
>> broke things out into different classes - but the threading is still the
>> same - and one specific problem I'm having is this.
>>
>> Within the worker thread, I do this:
>>
>> ListViewItem lvwItem = new ListViewItem();
>>
>> I want to try to do as much work as possible, while leaving a lot of
>> potential functionality in the worker thread. So I'd like to pre-populate
>> a ListViewItem - and then do the Invoke to just add that pre-filled
>> ListViewItem to the listview on the UI.
>>
>> On that line, I get an error of:
>>
>> Illegal cross-thread operation: Control 'frmPopup' accessed from a thread
>> other than the thread it was created on.
>> Stack trace where the illegal operation occurred was:
>>
>> at System.Windows.Forms.Control.get_Handle() etc, etc
>>
>> And it happens right at that line above when I'm trying to create a
>> ListViewItem programatically. I am assuming that when you create a UI
>> element programatically, it needs a window handle? If so - how do I get
>> around this? And I know I've had this work before, the only thing
>> different is I have this functionality in a seperate class.
>>
>> Also - I got rid of 100% of the functionality in that thread (commented
>> it
>> out) - and slowly added lines back in, and this is the only, even remote
>> reference to a UI element in this chunk of code, and this is the specific
>> line that throws the exception.
>>
>> Any ideas???[/color]
>
> --
> Texeme
> http://texeme.com
>[/color] | | | | re: Threading with UI elements - dynamically created controls?
RCS wrote:
[color=blue]
> Windows doesn't allow a secondary thread to update any UI elements.[/color]
I'm not saying it should.
I'm saying you can return a new object -- which has the values you want, and
then in the main thread, update the UI element with that value.
[color=blue]
> You
> have to have the original UI thread do that. So what you can do from the
> secondary thread is:
>
> if ( InvokeRequired )
> {
> BeginInvoke(...)
> }
> // Do the real work here
>
>
> That part of this, is all good and works fine. There is somewhat of a
> detailed class that handles all the UI elements that I'd need to update
> from a background thread. But way before I get to that, and to address
> what you've asked. From the UI thread I do this to start things off:
>
>
> System.Threading.ThreadStart objTS = new System.Threading.ThreadStart(
> LoadListView1 );
> System.Threading.Thread objThread = new System.Threading.Thread( objTS );
> objThread.Name = "LoadListView1";
> objThread.Start();
>
>
> Then, within that function, I am immediately doing this:
>
>
> ListViewItem lvwItem = new ListViewItem();
>
>
> That is enough to make it fail. So, I'm not actually trying to update any
> UI elements on a form, at this point - I'm just programatically creating a
> UI element that will be added to one of my forms later.
>
>
>
> "Elidel" <im@elidel.l.eh.del> wrote in message
> news:rX8Nd.1166$UX3.1062@newsread3.news.pas.earthl ink.net...[color=green]
>>
>> I don't know how your creating your thread, but it sounds like the error
>> is
>> in how you pass back the result to the main ( calling ) thread.
>>
>> So, for example, if you try to add lvwItem to frmPopup in the spawned
>> thread
>> you might get that error.
>>
>> If you set up, say, a thread pool, that calls a method that returns
>> ListViewItem as a result, and then add it to frmPopup control array, that
>> might be different.
>>
>> RCS wrote:
>>[color=darkred]
>>>
>>> I have a UI that needs a couple of threads to do some significant
>>> processing on a couple of different forms - and while it's at it, update
>>> the UI (set textboxes, fill in listviews). I created a base class for
>>> the worker class, and made up some functions/delegates to handle the
>>> invoke stuff for the UI and that was fine for a prototype. I rewrote
>>> this chunk, broke things out into different classes - but the threading
>>> is still the same - and one specific problem I'm having is this.
>>>
>>> Within the worker thread, I do this:
>>>
>>> ListViewItem lvwItem = new ListViewItem();
>>>
>>> I want to try to do as much work as possible, while leaving a lot of
>>> potential functionality in the worker thread. So I'd like to
>>> pre-populate a ListViewItem - and then do the Invoke to just add that
>>> pre-filled ListViewItem to the listview on the UI.
>>>
>>> On that line, I get an error of:
>>>
>>> Illegal cross-thread operation: Control 'frmPopup' accessed from a
>>> thread other than the thread it was created on.
>>> Stack trace where the illegal operation occurred was:
>>>
>>> at System.Windows.Forms.Control.get_Handle() etc, etc
>>>
>>> And it happens right at that line above when I'm trying to create a
>>> ListViewItem programatically. I am assuming that when you create a UI
>>> element programatically, it needs a window handle? If so - how do I get
>>> around this? And I know I've had this work before, the only thing
>>> different is I have this functionality in a seperate class.
>>>
>>> Also - I got rid of 100% of the functionality in that thread (commented
>>> it
>>> out) - and slowly added lines back in, and this is the only, even remote
>>> reference to a UI element in this chunk of code, and this is the
>>> specific line that throws the exception.
>>>
>>> Any ideas???[/color]
>>
>> --
>> Texeme
>> http://texeme.com
>>[/color][/color]
--
Texeme http://texeme.com | | | | re: Threading with UI elements - dynamically created controls?
RCS wrote:
[color=blue]
> System.Threading.ThreadStart objTS = new System.Threading.ThreadStart(
> LoadListView1 );
> System.Threading.Thread objThread = new System.Threading.Thread( objTS );
> objThread.Name = "LoadListView1";
> objThread.Start();
>
>
> Then, within that function, I am immediately doing this:
>
>
> ListViewItem lvwItem = new ListViewItem();[/color]
And you then get the error:
[color=blue]
>
>
> That is enough to make it fail. So, I'm not actually trying to update any
> UI elements on a form, at this point - I'm just programatically creating a
> UI element that will be added to one of my forms later.
>
>
>
> "Elidel" <im@elidel.l.eh.del> wrote in message
> news:rX8Nd.1166$UX3.1062@newsread3.news.pas.earthl ink.net...[color=green]
>>
>> I don't know how your creating your thread, but it sounds like the error
>> is
>> in how you pass back the result to the main ( calling ) thread.
>>
>> So, for example, if you try to add lvwItem to frmPopup in the spawned
>> thread
>> you might get that error.
>>
>> If you set up, say, a thread pool, that calls a method that returns
>> ListViewItem as a result, and then add it to frmPopup control array, that
>> might be different.
>>
>> RCS wrote:
>>[color=darkred]
>>>
>>> I have a UI that needs a couple of threads to do some significant
>>> processing on a couple of different forms - and while it's at it, update
>>> the UI (set textboxes, fill in listviews). I created a base class for
>>> the worker class, and made up some functions/delegates to handle the
>>> invoke stuff for the UI and that was fine for a prototype. I rewrote
>>> this chunk, broke things out into different classes - but the threading
>>> is still the same - and one specific problem I'm having is this.
>>>
>>> Within the worker thread, I do this:
>>>
>>> ListViewItem lvwItem = new ListViewItem();
>>>
>>> I want to try to do as much work as possible, while leaving a lot of
>>> potential functionality in the worker thread. So I'd like to
>>> pre-populate a ListViewItem - and then do the Invoke to just add that
>>> pre-filled ListViewItem to the listview on the UI.
>>>
>>> On that line, I get an error of:
>>>
>>> Illegal cross-thread operation: Control 'frmPopup' accessed from a
>>> thread other than the thread it was created on.
>>> Stack trace where the illegal operation occurred was:
>>>
>>> at System.Windows.Forms.Control.get_Handle() etc, etc
>>>
>>> And it happens right at that line above when I'm trying to create a
>>> ListViewItem programatically. I am assuming that when you create a UI
>>> element programatically, it needs a window handle? If so - how do I get
>>> around this? And I know I've had this work before, the only thing
>>> different is I have this functionality in a seperate class.
>>>
>>> Also - I got rid of 100% of the functionality in that thread (commented
>>> it
>>> out) - and slowly added lines back in, and this is the only, even remote
>>> reference to a UI element in this chunk of code, and this is the
>>> specific line that throws the exception.
>>>
>>> Any ideas???[/color]
>>
>> --
>> Texeme
>> http://texeme.com
>>[/color][/color]
--
Texeme http://texeme.com | | | | re: Threading with UI elements - dynamically created controls?
RCS wrote:
[color=blue]
> System.Threading.ThreadStart objTS = new System.Threading.ThreadStart(
> LoadListView1 );
> System.Threading.Thread objThread = new System.Threading.Thread( objTS );
> objThread.Name = "LoadListView1";
> objThread.Start();
>
>
> Then, within that function, I am immediately doing this:
>
>
> ListViewItem lvwItem = new ListViewItem();[/color]
And you then get the error:
Control 'frmPopup' accessed from a thread ?
What does objTS look like ?
[color=blue]
>
>
> That is enough to make it fail. So, I'm not actually trying to update any
> UI elements on a form, at this point - I'm just programatically creating a
> UI element that will be added to one of my forms later.
>
>
>
> "Elidel" <im@elidel.l.eh.del> wrote in message
> news:rX8Nd.1166$UX3.1062@newsread3.news.pas.earthl ink.net...[color=green]
>>
>> I don't know how your creating your thread, but it sounds like the error
>> is
>> in how you pass back the result to the main ( calling ) thread.
>>
>> So, for example, if you try to add lvwItem to frmPopup in the spawned
>> thread
>> you might get that error.
>>
>> If you set up, say, a thread pool, that calls a method that returns
>> ListViewItem as a result, and then add it to frmPopup control array, that
>> might be different.
>>
>> RCS wrote:
>>[color=darkred]
>>>
>>> I have a UI that needs a couple of threads to do some significant
>>> processing on a couple of different forms - and while it's at it, update
>>> the UI (set textboxes, fill in listviews). I created a base class for
>>> the worker class, and made up some functions/delegates to handle the
>>> invoke stuff for the UI and that was fine for a prototype. I rewrote
>>> this chunk, broke things out into different classes - but the threading
>>> is still the same - and one specific problem I'm having is this.
>>>
>>> Within the worker thread, I do this:
>>>
>>> ListViewItem lvwItem = new ListViewItem();
>>>
>>> I want to try to do as much work as possible, while leaving a lot of
>>> potential functionality in the worker thread. So I'd like to
>>> pre-populate a ListViewItem - and then do the Invoke to just add that
>>> pre-filled ListViewItem to the listview on the UI.
>>>
>>> On that line, I get an error of:
>>>
>>> Illegal cross-thread operation: Control 'frmPopup' accessed from a
>>> thread other than the thread it was created on.
>>> Stack trace where the illegal operation occurred was:
>>>
>>> at System.Windows.Forms.Control.get_Handle() etc, etc
>>>
>>> And it happens right at that line above when I'm trying to create a
>>> ListViewItem programatically. I am assuming that when you create a UI
>>> element programatically, it needs a window handle? If so - how do I get
>>> around this? And I know I've had this work before, the only thing
>>> different is I have this functionality in a seperate class.
>>>
>>> Also - I got rid of 100% of the functionality in that thread (commented
>>> it
>>> out) - and slowly added lines back in, and this is the only, even remote
>>> reference to a UI element in this chunk of code, and this is the
>>> specific line that throws the exception.
>>>
>>> Any ideas???[/color]
>>
>> --
>> Texeme
>> http://texeme.com
>>[/color][/color]
--
Texeme http://texeme.com | | | | re: Threading with UI elements - dynamically created controls?
Elidel wrote:
Or rather, what does LoadListView1 look like ?
[color=blue]
> RCS wrote:
>[color=green]
>> Windows doesn't allow a secondary thread to update any UI elements.[/color]
>
> I'm not saying it should.
>
> I'm saying you can return a new object -- which has the values you want,
> and then in the main thread, update the UI element with that value.
>
>[color=green]
>> You
>> have to have the original UI thread do that. So what you can do from the
>> secondary thread is:
>>
>> if ( InvokeRequired )
>> {
>> BeginInvoke(...)
>> }
>> // Do the real work here
>>
>>
>> That part of this, is all good and works fine. There is somewhat of a
>> detailed class that handles all the UI elements that I'd need to update
>> from a background thread. But way before I get to that, and to address
>> what you've asked. From the UI thread I do this to start things off:
>>
>>
>> System.Threading.ThreadStart objTS = new System.Threading.ThreadStart(
>> LoadListView1 );
>> System.Threading.Thread objThread = new System.Threading.Thread( objTS );
>> objThread.Name = "LoadListView1";
>> objThread.Start();
>>
>>
>> Then, within that function, I am immediately doing this:
>>
>>
>> ListViewItem lvwItem = new ListViewItem();
>>
>>
>> That is enough to make it fail. So, I'm not actually trying to update any
>> UI elements on a form, at this point - I'm just programatically creating
>> a UI element that will be added to one of my forms later.
>>
>>
>>
>> "Elidel" <im@elidel.l.eh.del> wrote in message
>> news:rX8Nd.1166$UX3.1062@newsread3.news.pas.earthl ink.net...[color=darkred]
>>>
>>> I don't know how your creating your thread, but it sounds like the error
>>> is
>>> in how you pass back the result to the main ( calling ) thread.
>>>
>>> So, for example, if you try to add lvwItem to frmPopup in the spawned
>>> thread
>>> you might get that error.
>>>
>>> If you set up, say, a thread pool, that calls a method that returns
>>> ListViewItem as a result, and then add it to frmPopup control array,
>>> that might be different.
>>>
>>> RCS wrote:
>>>
>>>>
>>>> I have a UI that needs a couple of threads to do some significant
>>>> processing on a couple of different forms - and while it's at it,
>>>> update the UI (set textboxes, fill in listviews). I created a base
>>>> class for the worker class, and made up some functions/delegates to
>>>> handle the invoke stuff for the UI and that was fine for a prototype. I
>>>> rewrote this chunk, broke things out into different classes - but the
>>>> threading is still the same - and one specific problem I'm having is
>>>> this.
>>>>
>>>> Within the worker thread, I do this:
>>>>
>>>> ListViewItem lvwItem = new ListViewItem();
>>>>
>>>> I want to try to do as much work as possible, while leaving a lot of
>>>> potential functionality in the worker thread. So I'd like to
>>>> pre-populate a ListViewItem - and then do the Invoke to just add that
>>>> pre-filled ListViewItem to the listview on the UI.
>>>>
>>>> On that line, I get an error of:
>>>>
>>>> Illegal cross-thread operation: Control 'frmPopup' accessed from a
>>>> thread other than the thread it was created on.
>>>> Stack trace where the illegal operation occurred was:
>>>>
>>>> at System.Windows.Forms.Control.get_Handle() etc, etc
>>>>
>>>> And it happens right at that line above when I'm trying to create a
>>>> ListViewItem programatically. I am assuming that when you create a UI
>>>> element programatically, it needs a window handle? If so - how do I get
>>>> around this? And I know I've had this work before, the only thing
>>>> different is I have this functionality in a seperate class.
>>>>
>>>> Also - I got rid of 100% of the functionality in that thread (commented
>>>> it
>>>> out) - and slowly added lines back in, and this is the only, even
>>>> remote reference to a UI element in this chunk of code, and this is the
>>>> specific line that throws the exception.
>>>>
>>>> Any ideas???
>>>
>>> --
>>> Texeme
>>> http://texeme.com
>>>[/color][/color]
>[/color]
--
Texeme http://texeme.com | | | | re: Threading with UI elements - dynamically created controls?
That's it - just one line in it:
ListViewItem lvwItem = new ListViewItem();
"Elidel" <im@elidel.l.eh.del> wrote in message
news:CX9Nd.1148$mG6.23@newsread1.news.pas.earthlin k.net...[color=blue]
> Elidel wrote:
>
> Or rather, what does LoadListView1 look like ?
>[color=green]
>> RCS wrote:
>>[color=darkred]
>>> Windows doesn't allow a secondary thread to update any UI elements.[/color]
>>
>> I'm not saying it should.
>>
>> I'm saying you can return a new object -- which has the values you want,
>> and then in the main thread, update the UI element with that value.
>>
>>[color=darkred]
>>> You
>>> have to have the original UI thread do that. So what you can do from the
>>> secondary thread is:
>>>
>>> if ( InvokeRequired )
>>> {
>>> BeginInvoke(...)
>>> }
>>> // Do the real work here
>>>
>>>
>>> That part of this, is all good and works fine. There is somewhat of a
>>> detailed class that handles all the UI elements that I'd need to update
>>> from a background thread. But way before I get to that, and to address
>>> what you've asked. From the UI thread I do this to start things off:
>>>
>>>
>>> System.Threading.ThreadStart objTS = new System.Threading.ThreadStart(
>>> LoadListView1 );
>>> System.Threading.Thread objThread = new System.Threading.Thread(
>>> objTS );
>>> objThread.Name = "LoadListView1";
>>> objThread.Start();
>>>
>>>
>>> Then, within that function, I am immediately doing this:
>>>
>>>
>>> ListViewItem lvwItem = new ListViewItem();
>>>
>>>
>>> That is enough to make it fail. So, I'm not actually trying to update
>>> any
>>> UI elements on a form, at this point - I'm just programatically creating
>>> a UI element that will be added to one of my forms later.
>>>
>>>
>>>
>>> "Elidel" <im@elidel.l.eh.del> wrote in message
>>> news:rX8Nd.1166$UX3.1062@newsread3.news.pas.earthl ink.net...
>>>>
>>>> I don't know how your creating your thread, but it sounds like the
>>>> error
>>>> is
>>>> in how you pass back the result to the main ( calling ) thread.
>>>>
>>>> So, for example, if you try to add lvwItem to frmPopup in the spawned
>>>> thread
>>>> you might get that error.
>>>>
>>>> If you set up, say, a thread pool, that calls a method that returns
>>>> ListViewItem as a result, and then add it to frmPopup control array,
>>>> that might be different.
>>>>
>>>> RCS wrote:
>>>>
>>>>>
>>>>> I have a UI that needs a couple of threads to do some significant
>>>>> processing on a couple of different forms - and while it's at it,
>>>>> update the UI (set textboxes, fill in listviews). I created a base
>>>>> class for the worker class, and made up some functions/delegates to
>>>>> handle the invoke stuff for the UI and that was fine for a prototype.
>>>>> I
>>>>> rewrote this chunk, broke things out into different classes - but the
>>>>> threading is still the same - and one specific problem I'm having is
>>>>> this.
>>>>>
>>>>> Within the worker thread, I do this:
>>>>>
>>>>> ListViewItem lvwItem = new ListViewItem();
>>>>>
>>>>> I want to try to do as much work as possible, while leaving a lot of
>>>>> potential functionality in the worker thread. So I'd like to
>>>>> pre-populate a ListViewItem - and then do the Invoke to just add that
>>>>> pre-filled ListViewItem to the listview on the UI.
>>>>>
>>>>> On that line, I get an error of:
>>>>>
>>>>> Illegal cross-thread operation: Control 'frmPopup' accessed from a
>>>>> thread other than the thread it was created on.
>>>>> Stack trace where the illegal operation occurred was:
>>>>>
>>>>> at System.Windows.Forms.Control.get_Handle() etc, etc
>>>>>
>>>>> And it happens right at that line above when I'm trying to create a
>>>>> ListViewItem programatically. I am assuming that when you create a UI
>>>>> element programatically, it needs a window handle? If so - how do I
>>>>> get
>>>>> around this? And I know I've had this work before, the only thing
>>>>> different is I have this functionality in a seperate class.
>>>>>
>>>>> Also - I got rid of 100% of the functionality in that thread
>>>>> (commented
>>>>> it
>>>>> out) - and slowly added lines back in, and this is the only, even
>>>>> remote reference to a UI element in this chunk of code, and this is
>>>>> the
>>>>> specific line that throws the exception.
>>>>>
>>>>> Any ideas???
>>>>
>>>> --
>>>> Texeme
>>>> http://texeme.com
>>>>[/color]
>>[/color]
>
> --
> Texeme
> http://texeme.com
>[/color] | | | | re: Threading with UI elements - dynamically created controls?
No no, that's a rule in Windows programming. You can't reference a loaded UI
object that was not created in your thread - you get a runtime error (this
is VS.NET 2K5 beta 1 by the way - I believe it was allowed in VS.NET 2K3)
"Elidel" <im@elidel.l.eh.del> wrote in message
news:QS9Nd.1143$mG6.1009@newsread1.news.pas.earthl ink.net...[color=blue]
> RCS wrote:
>[color=green]
>> Windows doesn't allow a secondary thread to update any UI elements.[/color]
>
> I'm not saying it should.
>
> I'm saying you can return a new object -- which has the values you want,
> and
> then in the main thread, update the UI element with that value.
>
>[color=green]
>> You
>> have to have the original UI thread do that. So what you can do from the
>> secondary thread is:
>>
>> if ( InvokeRequired )
>> {
>> BeginInvoke(...)
>> }
>> // Do the real work here
>>
>>
>> That part of this, is all good and works fine. There is somewhat of a
>> detailed class that handles all the UI elements that I'd need to update
>> from a background thread. But way before I get to that, and to address
>> what you've asked. From the UI thread I do this to start things off:
>>
>>
>> System.Threading.ThreadStart objTS = new System.Threading.ThreadStart(
>> LoadListView1 );
>> System.Threading.Thread objThread = new System.Threading.Thread( objTS );
>> objThread.Name = "LoadListView1";
>> objThread.Start();
>>
>>
>> Then, within that function, I am immediately doing this:
>>
>>
>> ListViewItem lvwItem = new ListViewItem();
>>
>>
>> That is enough to make it fail. So, I'm not actually trying to update any
>> UI elements on a form, at this point - I'm just programatically creating
>> a
>> UI element that will be added to one of my forms later.
>>
>>
>>
>> "Elidel" <im@elidel.l.eh.del> wrote in message
>> news:rX8Nd.1166$UX3.1062@newsread3.news.pas.earthl ink.net...[color=darkred]
>>>
>>> I don't know how your creating your thread, but it sounds like the error
>>> is
>>> in how you pass back the result to the main ( calling ) thread.
>>>
>>> So, for example, if you try to add lvwItem to frmPopup in the spawned
>>> thread
>>> you might get that error.
>>>
>>> If you set up, say, a thread pool, that calls a method that returns
>>> ListViewItem as a result, and then add it to frmPopup control array,
>>> that
>>> might be different.
>>>
>>> RCS wrote:
>>>
>>>>
>>>> I have a UI that needs a couple of threads to do some significant
>>>> processing on a couple of different forms - and while it's at it,
>>>> update
>>>> the UI (set textboxes, fill in listviews). I created a base class for
>>>> the worker class, and made up some functions/delegates to handle the
>>>> invoke stuff for the UI and that was fine for a prototype. I rewrote
>>>> this chunk, broke things out into different classes - but the threading
>>>> is still the same - and one specific problem I'm having is this.
>>>>
>>>> Within the worker thread, I do this:
>>>>
>>>> ListViewItem lvwItem = new ListViewItem();
>>>>
>>>> I want to try to do as much work as possible, while leaving a lot of
>>>> potential functionality in the worker thread. So I'd like to
>>>> pre-populate a ListViewItem - and then do the Invoke to just add that
>>>> pre-filled ListViewItem to the listview on the UI.
>>>>
>>>> On that line, I get an error of:
>>>>
>>>> Illegal cross-thread operation: Control 'frmPopup' accessed from a
>>>> thread other than the thread it was created on.
>>>> Stack trace where the illegal operation occurred was:
>>>>
>>>> at System.Windows.Forms.Control.get_Handle() etc, etc
>>>>
>>>> And it happens right at that line above when I'm trying to create a
>>>> ListViewItem programatically. I am assuming that when you create a UI
>>>> element programatically, it needs a window handle? If so - how do I get
>>>> around this? And I know I've had this work before, the only thing
>>>> different is I have this functionality in a seperate class.
>>>>
>>>> Also - I got rid of 100% of the functionality in that thread (commented
>>>> it
>>>> out) - and slowly added lines back in, and this is the only, even
>>>> remote
>>>> reference to a UI element in this chunk of code, and this is the
>>>> specific line that throws the exception.
>>>>
>>>> Any ideas???
>>>
>>> --
>>> Texeme
>>> http://texeme.com
>>>[/color][/color]
>
> --
> Texeme
> http://texeme.com
>[/color] | | | | re: Threading with UI elements - dynamically created controls?
RCS wrote:
So the idea is
1. Create a ListView0 in the main thread.
2. Spawn the thread, create the ListView1 with data.
3. Take the return value of the threaded method, and set
ListView0 = ListView1
[color=blue]
>
> No no, that's a rule in Windows programming. You can't reference a loaded
> UI object that was not created in your thread - you get a runtime error
> (this is VS.NET 2K5 beta 1 by the way - I believe it was allowed in VS.NET
> 2K3)
>
> "Elidel" <im@elidel.l.eh.del> wrote in message
> news:QS9Nd.1143$mG6.1009@newsread1.news.pas.earthl ink.net...[color=green]
>> RCS wrote:
>>[color=darkred]
>>> Windows doesn't allow a secondary thread to update any UI elements.[/color]
>>
>> I'm not saying it should.
>>
>> I'm saying you can return a new object -- which has the values you want,
>> and
>> then in the main thread, update the UI element with that value.
>>
>>[color=darkred]
>>> You
>>> have to have the original UI thread do that. So what you can do from the
>>> secondary thread is:
>>>
>>> if ( InvokeRequired )
>>> {
>>> BeginInvoke(...)
>>> }
>>> // Do the real work here
>>>
>>>
>>> That part of this, is all good and works fine. There is somewhat of a
>>> detailed class that handles all the UI elements that I'd need to update
>>> from a background thread. But way before I get to that, and to address
>>> what you've asked. From the UI thread I do this to start things off:
>>>
>>>
>>> System.Threading.ThreadStart objTS = new System.Threading.ThreadStart(
>>> LoadListView1 );
>>> System.Threading.Thread objThread = new System.Threading.Thread( objTS
>>> ); objThread.Name = "LoadListView1";
>>> objThread.Start();
>>>
>>>
>>> Then, within that function, I am immediately doing this:
>>>
>>>
>>> ListViewItem lvwItem = new ListViewItem();
>>>
>>>
>>> That is enough to make it fail. So, I'm not actually trying to update
>>> any UI elements on a form, at this point - I'm just programatically
>>> creating a
>>> UI element that will be added to one of my forms later.
>>>
>>>
>>>
>>> "Elidel" <im@elidel.l.eh.del> wrote in message
>>> news:rX8Nd.1166$UX3.1062@newsread3.news.pas.earthl ink.net...
>>>>
>>>> I don't know how your creating your thread, but it sounds like the
>>>> error is
>>>> in how you pass back the result to the main ( calling ) thread.
>>>>
>>>> So, for example, if you try to add lvwItem to frmPopup in the spawned
>>>> thread
>>>> you might get that error.
>>>>
>>>> If you set up, say, a thread pool, that calls a method that returns
>>>> ListViewItem as a result, and then add it to frmPopup control array,
>>>> that
>>>> might be different.
>>>>
>>>> RCS wrote:
>>>>
>>>>>
>>>>> I have a UI that needs a couple of threads to do some significant
>>>>> processing on a couple of different forms - and while it's at it,
>>>>> update
>>>>> the UI (set textboxes, fill in listviews). I created a base class for
>>>>> the worker class, and made up some functions/delegates to handle the
>>>>> invoke stuff for the UI and that was fine for a prototype. I rewrote
>>>>> this chunk, broke things out into different classes - but the
>>>>> threading is still the same - and one specific problem I'm having is
>>>>> this.
>>>>>
>>>>> Within the worker thread, I do this:
>>>>>
>>>>> ListViewItem lvwItem = new ListViewItem();
>>>>>
>>>>> I want to try to do as much work as possible, while leaving a lot of
>>>>> potential functionality in the worker thread. So I'd like to
>>>>> pre-populate a ListViewItem - and then do the Invoke to just add that
>>>>> pre-filled ListViewItem to the listview on the UI.
>>>>>
>>>>> On that line, I get an error of:
>>>>>
>>>>> Illegal cross-thread operation: Control 'frmPopup' accessed from a
>>>>> thread other than the thread it was created on.
>>>>> Stack trace where the illegal operation occurred was:
>>>>>
>>>>> at System.Windows.Forms.Control.get_Handle() etc, etc
>>>>>
>>>>> And it happens right at that line above when I'm trying to create a
>>>>> ListViewItem programatically. I am assuming that when you create a UI
>>>>> element programatically, it needs a window handle? If so - how do I
>>>>> get around this? And I know I've had this work before, the only thing
>>>>> different is I have this functionality in a seperate class.
>>>>>
>>>>> Also - I got rid of 100% of the functionality in that thread
>>>>> (commented it
>>>>> out) - and slowly added lines back in, and this is the only, even
>>>>> remote
>>>>> reference to a UI element in this chunk of code, and this is the
>>>>> specific line that throws the exception.
>>>>>
>>>>> Any ideas???
>>>>
>>>> --
>>>> Texeme
>>>> http://texeme.com
>>>>[/color]
>>
>> --
>> Texeme
>> http://texeme.com
>>[/color][/color]
--
Texeme http://texeme.com | | | | re: Threading with UI elements - dynamically created controls?
Well, I'd rather not do that, because there are a lot of screens and lot of
different UI elements - and I'd rather do it the proper way. Ideally:
UI Thread:
Draw the interface, create a listview, spawn a new thread that does
"something", then sit idle
Background Thread:
Dynamically create an unbound programatic ListViewItem (an item that is in a
ListView) - populate that, then BeginInvoke to the UI thread to have it add
the new row.
meanwhile, the idle UI thread gets a BeginInvoke to insert a new
ListViewItem.. a couple of these listviews update over time.. so
pre-loading them, then copying them would be bulky and messy. I want to be
able to do this one row at a time..
thanks
"Elidel" <im@elidel.l.eh.del> wrote in message
news:WJbNd.1275$UX3.1046@newsread3.news.pas.earthl ink.net...[color=blue]
> RCS wrote:
>
> So the idea is
>
> 1. Create a ListView0 in the main thread.
> 2. Spawn the thread, create the ListView1 with data.
> 3. Take the return value of the threaded method, and set
>
> ListView0 = ListView1
>
>[color=green]
>>
>> No no, that's a rule in Windows programming. You can't reference a loaded
>> UI object that was not created in your thread - you get a runtime error
>> (this is VS.NET 2K5 beta 1 by the way - I believe it was allowed in
>> VS.NET
>> 2K3)
>>
>> "Elidel" <im@elidel.l.eh.del> wrote in message
>> news:QS9Nd.1143$mG6.1009@newsread1.news.pas.earthl ink.net...[color=darkred]
>>> RCS wrote:
>>>
>>>> Windows doesn't allow a secondary thread to update any UI elements.
>>>
>>> I'm not saying it should.
>>>
>>> I'm saying you can return a new object -- which has the values you want,
>>> and
>>> then in the main thread, update the UI element with that value.
>>>
>>>
>>>> You
>>>> have to have the original UI thread do that. So what you can do from
>>>> the
>>>> secondary thread is:
>>>>
>>>> if ( InvokeRequired )
>>>> {
>>>> BeginInvoke(...)
>>>> }
>>>> // Do the real work here
>>>>
>>>>
>>>> That part of this, is all good and works fine. There is somewhat of a
>>>> detailed class that handles all the UI elements that I'd need to update
>>>> from a background thread. But way before I get to that, and to address
>>>> what you've asked. From the UI thread I do this to start things off:
>>>>
>>>>
>>>> System.Threading.ThreadStart objTS = new System.Threading.ThreadStart(
>>>> LoadListView1 );
>>>> System.Threading.Thread objThread = new System.Threading.Thread( objTS
>>>> ); objThread.Name = "LoadListView1";
>>>> objThread.Start();
>>>>
>>>>
>>>> Then, within that function, I am immediately doing this:
>>>>
>>>>
>>>> ListViewItem lvwItem = new ListViewItem();
>>>>
>>>>
>>>> That is enough to make it fail. So, I'm not actually trying to update
>>>> any UI elements on a form, at this point - I'm just programatically
>>>> creating a
>>>> UI element that will be added to one of my forms later.
>>>>
>>>>
>>>>
>>>> "Elidel" <im@elidel.l.eh.del> wrote in message
>>>> news:rX8Nd.1166$UX3.1062@newsread3.news.pas.earthl ink.net...
>>>>>
>>>>> I don't know how your creating your thread, but it sounds like the
>>>>> error is
>>>>> in how you pass back the result to the main ( calling ) thread.
>>>>>
>>>>> So, for example, if you try to add lvwItem to frmPopup in the spawned
>>>>> thread
>>>>> you might get that error.
>>>>>
>>>>> If you set up, say, a thread pool, that calls a method that returns
>>>>> ListViewItem as a result, and then add it to frmPopup control array,
>>>>> that
>>>>> might be different.
>>>>>
>>>>> RCS wrote:
>>>>>
>>>>>>
>>>>>> I have a UI that needs a couple of threads to do some significant
>>>>>> processing on a couple of different forms - and while it's at it,
>>>>>> update
>>>>>> the UI (set textboxes, fill in listviews). I created a base class for
>>>>>> the worker class, and made up some functions/delegates to handle the
>>>>>> invoke stuff for the UI and that was fine for a prototype. I rewrote
>>>>>> this chunk, broke things out into different classes - but the
>>>>>> threading is still the same - and one specific problem I'm having is
>>>>>> this.
>>>>>>
>>>>>> Within the worker thread, I do this:
>>>>>>
>>>>>> ListViewItem lvwItem = new ListViewItem();
>>>>>>
>>>>>> I want to try to do as much work as possible, while leaving a lot of
>>>>>> potential functionality in the worker thread. So I'd like to
>>>>>> pre-populate a ListViewItem - and then do the Invoke to just add that
>>>>>> pre-filled ListViewItem to the listview on the UI.
>>>>>>
>>>>>> On that line, I get an error of:
>>>>>>
>>>>>> Illegal cross-thread operation: Control 'frmPopup' accessed from a
>>>>>> thread other than the thread it was created on.
>>>>>> Stack trace where the illegal operation occurred was:
>>>>>>
>>>>>> at System.Windows.Forms.Control.get_Handle() etc, etc
>>>>>>
>>>>>> And it happens right at that line above when I'm trying to create a
>>>>>> ListViewItem programatically. I am assuming that when you create a UI
>>>>>> element programatically, it needs a window handle? If so - how do I
>>>>>> get around this? And I know I've had this work before, the only thing
>>>>>> different is I have this functionality in a seperate class.
>>>>>>
>>>>>> Also - I got rid of 100% of the functionality in that thread
>>>>>> (commented it
>>>>>> out) - and slowly added lines back in, and this is the only, even
>>>>>> remote
>>>>>> reference to a UI element in this chunk of code, and this is the
>>>>>> specific line that throws the exception.
>>>>>>
>>>>>> Any ideas???
>>>>>
>>>>> --
>>>>> Texeme
>>>>> http://texeme.com
>>>>>
>>>
>>> --
>>> Texeme
>>> http://texeme.com
>>>[/color][/color]
>
> --
> Texeme
> http://texeme.com
>[/color] | | | | re: Threading with UI elements - dynamically created controls?
RCS wrote:[color=blue]
> Well, I'd rather not do that, because there are a lot of screens and lot of
> different UI elements[/color]
Does this help: http://www.codeguru.com/columns/VB/print.php/c6553/
Asynchronous Programming with Thread Pools
Listing 1: Multithreading with an existing thread in ThreadPool.
1: Private Sub Form1_Load(ByVal sender As System.Object, _
2: ByVal e As System.EventArgs) Handles MyBase.Load
3:
4: ListBox1.Items.Clear()
5: ThreadPool.QueueUserWorkItem(AddressOf Initialize)
6:
7: End Sub
8:
9: Private Elem As String
10: Private Sub Add()
11: ListBox1.Items.Add(Elem)
12: Application.DoEvents()
13: End Sub
14:
15: Private Sub Initialize(ByVal State As Object)
16: Dim I As Integer
17:
18: SyncLock ListBox1.GetType
19:
20: For I = 10000000 To 1 Step -1
21: Elem = I
22: ListBox1.Invoke(CType(AddressOf Add, MethodInvoker))
23: Next
24:
25: End SyncLock
26:
27: End Sub
- and I'd rather do it the proper way. Ideally:[color=blue]
>
>
> UI Thread:
> Draw the interface, create a listview, spawn a new thread that does
> "something", then sit idle
>
> Background Thread:
> Dynamically create an unbound programatic ListViewItem (an item that is in a
> ListView) - populate that, then BeginInvoke to the UI thread to have it add
> the new row.
>
>
> meanwhile, the idle UI thread gets a BeginInvoke to insert a new
> ListViewItem.. a couple of these listviews update over time.. so
> pre-loading them, then copying them would be bulky and messy. I want to be
> able to do this one row at a time..
>
> thanks
>
>
> "Elidel" <im@elidel.l.eh.del> wrote in message
> news:WJbNd.1275$UX3.1046@newsread3.news.pas.earthl ink.net...
>[color=green]
>>RCS wrote:
>>
>>So the idea is
>>
>>1. Create a ListView0 in the main thread.
>>2. Spawn the thread, create the ListView1 with data.
>>3. Take the return value of the threaded method, and set
>>
>>ListView0 = ListView1
>>
>>
>>[color=darkred]
>>>No no, that's a rule in Windows programming. You can't reference a loaded
>>>UI object that was not created in your thread - you get a runtime error
>>>(this is VS.NET 2K5 beta 1 by the way - I believe it was allowed in
>>>VS.NET
>>>2K3)
>>>
>>>"Elidel" <im@elidel.l.eh.del> wrote in message
>>>news:QS9Nd.1143$mG6.1009@newsread1.news.pas.ear thlink.net...
>>>
>>>>RCS wrote:
>>>>
>>>>
>>>>>Windows doesn't allow a secondary thread to update any UI elements.
>>>>
>>>>I'm not saying it should.
>>>>
>>>>I'm saying you can return a new object -- which has the values you want,
>>>>and
>>>>then in the main thread, update the UI element with that value.
>>>>
>>>>
>>>>
>>>>>You
>>>>>have to have the original UI thread do that. So what you can do from
>>>>>the
>>>>>secondary thread is:
>>>>>
>>>>>if ( InvokeRequired )
>>>>>{
>>>>> BeginInvoke(...)
>>>>>}
>>>>>// Do the real work here
>>>>>
>>>>>
>>>>>That part of this, is all good and works fine. There is somewhat of a
>>>>>detailed class that handles all the UI elements that I'd need to update
>>>>>from a background thread. But way before I get to that, and to address
>>>>>what you've asked. From the UI thread I do this to start things off:
>>>>>
>>>>>
>>>>>System.Threading.ThreadStart objTS = new System.Threading.ThreadStart(
>>>>>LoadListView1 );
>>>>>System.Threading.Thread objThread = new System.Threading.Thread( objTS
>>>>>); objThread.Name = "LoadListView1";
>>>>>objThread.Start();
>>>>>
>>>>>
>>>>>Then, within that function, I am immediately doing this:
>>>>>
>>>>>
>>>>>ListViewItem lvwItem = new ListViewItem();
>>>>>
>>>>>
>>>>>That is enough to make it fail. So, I'm not actually trying to update
>>>>>any UI elements on a form, at this point - I'm just programatically
>>>>>creating a
>>>>>UI element that will be added to one of my forms later.
>>>>>
>>>>>
>>>>>
>>>>>"Elidel" <im@elidel.l.eh.del> wrote in message
>>>>>news:rX8Nd.1166$UX3.1062@newsread3.news.pas.e arthlink.net...
>>>>>
>>>>>>I don't know how your creating your thread, but it sounds like the
>>>>>>error is
>>>>>>in how you pass back the result to the main ( calling ) thread.
>>>>>>
>>>>>>So, for example, if you try to add lvwItem to frmPopup in the spawned
>>>>>>thread
>>>>>>you might get that error.
>>>>>>
>>>>>>If you set up, say, a thread pool, that calls a method that returns
>>>>>>ListViewItem as a result, and then add it to frmPopup control array,
>>>>>>that
>>>>>>might be different.
>>>>>>
>>>>>>RCS wrote:
>>>>>>
>>>>>>
>>>>>>>I have a UI that needs a couple of threads to do some significant
>>>>>>>processing on a couple of different forms - and while it's at it,
>>>>>>>update
>>>>>>>the UI (set textboxes, fill in listviews). I created a base class for
>>>>>>>the worker class, and made up some functions/delegates to handle the
>>>>>>>invoke stuff for the UI and that was fine for a prototype. I rewrote
>>>>>>>this chunk, broke things out into different classes - but the
>>>>>>>threading is still the same - and one specific problem I'm having is
>>>>>>>this.
>>>>>>>
>>>>>>>Within the worker thread, I do this:
>>>>>>>
>>>>>>>ListViewItem lvwItem = new ListViewItem();
>>>>>>>
>>>>>>>I want to try to do as much work as possible, while leaving a lot of
>>>>>>>potential functionality in the worker thread. So I'd like to
>>>>>>>pre-populate a ListViewItem - and then do the Invoke to just add that
>>>>>>>pre-filled ListViewItem to the listview on the UI.
>>>>>>>
>>>>>>>On that line, I get an error of:
>>>>>>>
>>>>>>>Illegal cross-thread operation: Control 'frmPopup' accessed from a
>>>>>>>thread other than the thread it was created on.
>>>>>>>Stack trace where the illegal operation occurred was:
>>>>>>>
>>>>>>>at System.Windows.Forms.Control.get_Handle() etc, etc
>>>>>>>
>>>>>>>And it happens right at that line above when I'm trying to create a
>>>>>>>ListViewItem programatically. I am assuming that when you create a UI
>>>>>>>element programatically, it needs a window handle? If so - how do I
>>>>>>>get around this? And I know I've had this work before, the only thing
>>>>>>>different is I have this functionality in a seperate class.
>>>>>>>
>>>>>>>Also - I got rid of 100% of the functionality in that thread
>>>>>>>(commented it
>>>>>>>out) - and slowly added lines back in, and this is the only, even
>>>>>>>remote
>>>>>>>reference to a UI element in this chunk of code, and this is the
>>>>>>>specific line that throws the exception.
>>>>>>>
>>>>>>>Any ideas???
>>>>>>
>>>>>>--
>>>>>>Texeme
>>>>>> http://texeme.com
>>>>>>
>>>>
>>>>--
>>>>Texeme
>>>> http://texeme.com
>>>>[/color]
>>
>>--
>>Texeme
>> http://texeme.com
>>[/color]
>
>
>[/color] | | | | re: Threading with UI elements - dynamically created controls?
Thanks for the help - this ended up being the VS.NET 2K5 beta 1 IDE messing
up - if I closed and re-opened the project, I get a different error, and it
still showed it was coming from the same line. That was not correct. I fixed
the error and all works fine.
I guess I shouldn't expect so much from a beta 1 product!!
"Elidel" <get.carter@wise.guy> wrote in message
news:FydNd.1316$UX3.932@newsread3.news.pas.earthli nk.net...[color=blue]
> RCS wrote:[color=green]
>> Well, I'd rather not do that, because there are a lot of screens and lot
>> of different UI elements[/color]
>
> Does this help:
>
> http://www.codeguru.com/columns/VB/print.php/c6553/
> Asynchronous Programming with Thread Pools
>
> Listing 1: Multithreading with an existing thread in ThreadPool.
>
> 1: Private Sub Form1_Load(ByVal sender As System.Object, _
> 2: ByVal e As System.EventArgs) Handles MyBase.Load
> 3:
> 4: ListBox1.Items.Clear()
> 5: ThreadPool.QueueUserWorkItem(AddressOf Initialize)
> 6:
> 7: End Sub
> 8:
> 9: Private Elem As String
> 10: Private Sub Add()
> 11: ListBox1.Items.Add(Elem)
> 12: Application.DoEvents()
> 13: End Sub
> 14:
> 15: Private Sub Initialize(ByVal State As Object)
> 16: Dim I As Integer
> 17:
> 18: SyncLock ListBox1.GetType
> 19:
> 20: For I = 10000000 To 1 Step -1
> 21: Elem = I
> 22: ListBox1.Invoke(CType(AddressOf Add, MethodInvoker))
> 23: Next
> 24:
> 25: End SyncLock
> 26:
> 27: End Sub
>
>
>
>
> - and I'd rather do it the proper way. Ideally:[color=green]
>>
>>
>> UI Thread:
>> Draw the interface, create a listview, spawn a new thread that does
>> "something", then sit idle
>>
>> Background Thread:
>> Dynamically create an unbound programatic ListViewItem (an item that is
>> in a ListView) - populate that, then BeginInvoke to the UI thread to have
>> it add the new row.
>>
>>
>> meanwhile, the idle UI thread gets a BeginInvoke to insert a new
>> ListViewItem.. a couple of these listviews update over time.. so
>> pre-loading them, then copying them would be bulky and messy. I want to
>> be able to do this one row at a time..
>>
>> thanks
>>
>>
>> "Elidel" <im@elidel.l.eh.del> wrote in message
>> news:WJbNd.1275$UX3.1046@newsread3.news.pas.earthl ink.net...
>>[color=darkred]
>>>RCS wrote:
>>>
>>>So the idea is
>>>
>>>1. Create a ListView0 in the main thread.
>>>2. Spawn the thread, create the ListView1 with data.
>>>3. Take the return value of the threaded method, and set
>>>
>>>ListView0 = ListView1
>>>
>>>
>>>
>>>>No no, that's a rule in Windows programming. You can't reference a
>>>>loaded
>>>>UI object that was not created in your thread - you get a runtime error
>>>>(this is VS.NET 2K5 beta 1 by the way - I believe it was allowed in
>>>>VS.NET
>>>>2K3)
>>>>
>>>>"Elidel" <im@elidel.l.eh.del> wrote in message
>>>>news:QS9Nd.1143$mG6.1009@newsread1.news.pas.ea rthlink.net...
>>>>
>>>>>RCS wrote:
>>>>>
>>>>>
>>>>>>Windows doesn't allow a secondary thread to update any UI elements.
>>>>>
>>>>>I'm not saying it should.
>>>>>
>>>>>I'm saying you can return a new object -- which has the values you
>>>>>want,
>>>>>and
>>>>>then in the main thread, update the UI element with that value.
>>>>>
>>>>>
>>>>>
>>>>>>You
>>>>>>have to have the original UI thread do that. So what you can do from
>>>>>>the
>>>>>>secondary thread is:
>>>>>>
>>>>>>if ( InvokeRequired )
>>>>>>{
>>>>>> BeginInvoke(...)
>>>>>>}
>>>>>>// Do the real work here
>>>>>>
>>>>>>
>>>>>>That part of this, is all good and works fine. There is somewhat of a
>>>>>>detailed class that handles all the UI elements that I'd need to
>>>>>>update
>>>>>>from a background thread. But way before I get to that, and to address
>>>>>>what you've asked. From the UI thread I do this to start things off:
>>>>>>
>>>>>>
>>>>>>System.Threading.ThreadStart objTS = new System.Threading.ThreadStart(
>>>>>>LoadListView1 );
>>>>>>System.Threading.Thread objThread = new System.Threading.Thread( objTS
>>>>>>); objThread.Name = "LoadListView1";
>>>>>>objThread.Start();
>>>>>>
>>>>>>
>>>>>>Then, within that function, I am immediately doing this:
>>>>>>
>>>>>>
>>>>>>ListViewItem lvwItem = new ListViewItem();
>>>>>>
>>>>>>
>>>>>>That is enough to make it fail. So, I'm not actually trying to update
>>>>>>any UI elements on a form, at this point - I'm just programatically
>>>>>>creating a
>>>>>>UI element that will be added to one of my forms later.
>>>>>>
>>>>>>
>>>>>>
>>>>>>"Elidel" <im@elidel.l.eh.del> wrote in message
>>>>>>news:rX8Nd.1166$UX3.1062@newsread3.news.pas. earthlink.net...
>>>>>>
>>>>>>>I don't know how your creating your thread, but it sounds like the
>>>>>>>error is
>>>>>>>in how you pass back the result to the main ( calling ) thread.
>>>>>>>
>>>>>>>So, for example, if you try to add lvwItem to frmPopup in the spawned
>>>>>>>thread
>>>>>>>you might get that error.
>>>>>>>
>>>>>>>If you set up, say, a thread pool, that calls a method that returns
>>>>>>>ListViewItem as a result, and then add it to frmPopup control array,
>>>>>>>that
>>>>>>>might be different.
>>>>>>>
>>>>>>>RCS wrote:
>>>>>>>
>>>>>>>
>>>>>>>>I have a UI that needs a couple of threads to do some significant
>>>>>>>>processing on a couple of different forms - and while it's at it,
>>>>>>>>update
>>>>>>>>the UI (set textboxes, fill in listviews). I created a base class
>>>>>>>>for
>>>>>>>>the worker class, and made up some functions/delegates to handle the
>>>>>>>>invoke stuff for the UI and that was fine for a prototype. I rewrote
>>>>>>>>this chunk, broke things out into different classes - but the
>>>>>>>>threading is still the same - and one specific problem I'm having is
>>>>>>>>this.
>>>>>>>>
>>>>>>>>Within the worker thread, I do this:
>>>>>>>>
>>>>>>>>ListViewItem lvwItem = new ListViewItem();
>>>>>>>>
>>>>>>>>I want to try to do as much work as possible, while leaving a lot of
>>>>>>>>potential functionality in the worker thread. So I'd like to
>>>>>>>>pre-populate a ListViewItem - and then do the Invoke to just add
>>>>>>>>that
>>>>>>>>pre-filled ListViewItem to the listview on the UI.
>>>>>>>>
>>>>>>>>On that line, I get an error of:
>>>>>>>>
>>>>>>>>Illegal cross-thread operation: Control 'frmPopup' accessed from a
>>>>>>>>thread other than the thread it was created on.
>>>>>>>>Stack trace where the illegal operation occurred was:
>>>>>>>>
>>>>>>>>at System.Windows.Forms.Control.get_Handle() etc, etc
>>>>>>>>
>>>>>>>>And it happens right at that line above when I'm trying to create a
>>>>>>>>ListViewItem programatically. I am assuming that when you create a
>>>>>>>>UI
>>>>>>>>element programatically, it needs a window handle? If so - how do I
>>>>>>>>get around this? And I know I've had this work before, the only
>>>>>>>>thing
>>>>>>>>different is I have this functionality in a seperate class.
>>>>>>>>
>>>>>>>>Also - I got rid of 100% of the functionality in that thread
>>>>>>>>(commented it
>>>>>>>>out) - and slowly added lines back in, and this is the only, even
>>>>>>>>remote
>>>>>>>>reference to a UI element in this chunk of code, and this is the
>>>>>>>>specific line that throws the exception.
>>>>>>>>
>>>>>>>>Any ideas???
>>>>>>>
>>>>>>>--
>>>>>>>Texeme
>>>>>>> http://texeme.com
>>>>>>>
>>>>>
>>>>>--
>>>>>Texeme
>>>>> http://texeme.com
>>>>>
>>>
>>>--
>>>Texeme
>>> http://texeme.com
>>>[/color]
>>
>>[/color][/color] | | | | re: Threading with UI elements - dynamically created controls?
RCS wrote:
[color=blue]
> Thanks for the help - this ended up being the VS.NET 2K5 beta 1 IDE
> messing up - if I closed and re-opened the project, I get a different
> error, and it still showed it was coming from the same line. That was not
> correct. I fixed the error and all works fine.[/color]
Rule one of support: make sure it's plugged in.
[color=blue]
>
> I guess I shouldn't expect so much from a beta 1 product!!
>
> "Elidel" <get.carter@wise.guy> wrote in message
> news:FydNd.1316$UX3.932@newsread3.news.pas.earthli nk.net...[color=green]
>> RCS wrote:[color=darkred]
>>> Well, I'd rather not do that, because there are a lot of screens and lot
>>> of different UI elements[/color]
>>
>> Does this help:
>>
>> http://www.codeguru.com/columns/VB/print.php/c6553/
>> Asynchronous Programming with Thread Pools
>>
>> Listing 1: Multithreading with an existing thread in ThreadPool.
>>
>> 1: Private Sub Form1_Load(ByVal sender As System.Object, _
>> 2: ByVal e As System.EventArgs) Handles MyBase.Load
>> 3:
>> 4: ListBox1.Items.Clear()
>> 5: ThreadPool.QueueUserWorkItem(AddressOf Initialize)
>> 6:
>> 7: End Sub
>> 8:
>> 9: Private Elem As String
>> 10: Private Sub Add()
>> 11: ListBox1.Items.Add(Elem)
>> 12: Application.DoEvents()
>> 13: End Sub
>> 14:
>> 15: Private Sub Initialize(ByVal State As Object)
>> 16: Dim I As Integer
>> 17:
>> 18: SyncLock ListBox1.GetType
>> 19:
>> 20: For I = 10000000 To 1 Step -1
>> 21: Elem = I
>> 22: ListBox1.Invoke(CType(AddressOf Add, MethodInvoker))
>> 23: Next
>> 24:
>> 25: End SyncLock
>> 26:
>> 27: End Sub
>>
>>
>>
>>
>> - and I'd rather do it the proper way. Ideally:[color=darkred]
>>>
>>>
>>> UI Thread:
>>> Draw the interface, create a listview, spawn a new thread that does
>>> "something", then sit idle
>>>
>>> Background Thread:
>>> Dynamically create an unbound programatic ListViewItem (an item that is
>>> in a ListView) - populate that, then BeginInvoke to the UI thread to
>>> have it add the new row.
>>>
>>>
>>> meanwhile, the idle UI thread gets a BeginInvoke to insert a new
>>> ListViewItem.. a couple of these listviews update over time.. so
>>> pre-loading them, then copying them would be bulky and messy. I want to
>>> be able to do this one row at a time..
>>>
>>> thanks
>>>
>>>
>>> "Elidel" <im@elidel.l.eh.del> wrote in message
>>> news:WJbNd.1275$UX3.1046@newsread3.news.pas.earthl ink.net...
>>>
>>>>RCS wrote:
>>>>
>>>>So the idea is
>>>>
>>>>1. Create a ListView0 in the main thread.
>>>>2. Spawn the thread, create the ListView1 with data.
>>>>3. Take the return value of the threaded method, and set
>>>>
>>>>ListView0 = ListView1
>>>>
>>>>
>>>>
>>>>>No no, that's a rule in Windows programming. You can't reference a
>>>>>loaded
>>>>>UI object that was not created in your thread - you get a runtime error
>>>>>(this is VS.NET 2K5 beta 1 by the way - I believe it was allowed in
>>>>>VS.NET
>>>>>2K3)
>>>>>
>>>>>"Elidel" <im@elidel.l.eh.del> wrote in message
>>>>>news:QS9Nd.1143$mG6.1009@newsread1.news.pas.e arthlink.net...
>>>>>
>>>>>>RCS wrote:
>>>>>>
>>>>>>
>>>>>>>Windows doesn't allow a secondary thread to update any UI elements.
>>>>>>
>>>>>>I'm not saying it should.
>>>>>>
>>>>>>I'm saying you can return a new object -- which has the values you
>>>>>>want,
>>>>>>and
>>>>>>then in the main thread, update the UI element with that value.
>>>>>>
>>>>>>
>>>>>>
>>>>>>>You
>>>>>>>have to have the original UI thread do that. So what you can do from
>>>>>>>the
>>>>>>>secondary thread is:
>>>>>>>
>>>>>>>if ( InvokeRequired )
>>>>>>>{
>>>>>>> BeginInvoke(...)
>>>>>>>}
>>>>>>>// Do the real work here
>>>>>>>
>>>>>>>
>>>>>>>That part of this, is all good and works fine. There is somewhat of a
>>>>>>>detailed class that handles all the UI elements that I'd need to
>>>>>>>update
>>>>>>>from a background thread. But way before I get to that, and to
>>>>>>>address what you've asked. From the UI thread I do this to start
>>>>>>>things off:
>>>>>>>
>>>>>>>
>>>>>>>System.Threading.ThreadStart objTS = new
>>>>>>>System.Threading.ThreadStart( LoadListView1 );
>>>>>>>System.Threading.Thread objThread = new System.Threading.Thread(
>>>>>>>objTS ); objThread.Name = "LoadListView1";
>>>>>>>objThread.Start();
>>>>>>>
>>>>>>>
>>>>>>>Then, within that function, I am immediately doing this:
>>>>>>>
>>>>>>>
>>>>>>>ListViewItem lvwItem = new ListViewItem();
>>>>>>>
>>>>>>>
>>>>>>>That is enough to make it fail. So, I'm not actually trying to update
>>>>>>>any UI elements on a form, at this point - I'm just programatically
>>>>>>>creating a
>>>>>>>UI element that will be added to one of my forms later.
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>"Elidel" <im@elidel.l.eh.del> wrote in message
>>>>>>>news:rX8Nd.1166$UX3.1062@newsread3.news.pas .earthlink.net...
>>>>>>>
>>>>>>>>I don't know how your creating your thread, but it sounds like the
>>>>>>>>error is
>>>>>>>>in how you pass back the result to the main ( calling ) thread.
>>>>>>>>
>>>>>>>>So, for example, if you try to add lvwItem to frmPopup in the
>>>>>>>>spawned thread
>>>>>>>>you might get that error.
>>>>>>>>
>>>>>>>>If you set up, say, a thread pool, that calls a method that returns
>>>>>>>>ListViewItem as a result, and then add it to frmPopup control array,
>>>>>>>>that
>>>>>>>>might be different.
>>>>>>>>
>>>>>>>>RCS wrote:
>>>>>>>>
>>>>>>>>
>>>>>>>>>I have a UI that needs a couple of threads to do some significant
>>>>>>>>>processing on a couple of different forms - and while it's at it,
>>>>>>>>>update
>>>>>>>>>the UI (set textboxes, fill in listviews). I created a base class
>>>>>>>>>for
>>>>>>>>>the worker class, and made up some functions/delegates to handle
>>>>>>>>>the invoke stuff for the UI and that was fine for a prototype. I
>>>>>>>>>rewrote this chunk, broke things out into different classes - but
>>>>>>>>>the threading is still the same - and one specific problem I'm
>>>>>>>>>having is this.
>>>>>>>>>
>>>>>>>>>Within the worker thread, I do this:
>>>>>>>>>
>>>>>>>>>ListViewItem lvwItem = new ListViewItem();
>>>>>>>>>
>>>>>>>>>I want to try to do as much work as possible, while leaving a lot
>>>>>>>>>of potential functionality in the worker thread. So I'd like to
>>>>>>>>>pre-populate a ListViewItem - and then do the Invoke to just add
>>>>>>>>>that
>>>>>>>>>pre-filled ListViewItem to the listview on the UI.
>>>>>>>>>
>>>>>>>>>On that line, I get an error of:
>>>>>>>>>
>>>>>>>>>Illegal cross-thread operation: Control 'frmPopup' accessed from a
>>>>>>>>>thread other than the thread it was created on.
>>>>>>>>>Stack trace where the illegal operation occurred was:
>>>>>>>>>
>>>>>>>>>at System.Windows.Forms.Control.get_Handle() etc, etc
>>>>>>>>>
>>>>>>>>>And it happens right at that line above when I'm trying to create a
>>>>>>>>>ListViewItem programatically. I am assuming that when you create a
>>>>>>>>>UI
>>>>>>>>>element programatically, it needs a window handle? If so - how do I
>>>>>>>>>get around this? And I know I've had this work before, the only
>>>>>>>>>thing
>>>>>>>>>different is I have this functionality in a seperate class.
>>>>>>>>>
>>>>>>>>>Also - I got rid of 100% of the functionality in that thread
>>>>>>>>>(commented it
>>>>>>>>>out) - and slowly added lines back in, and this is the only, even
>>>>>>>>>remote
>>>>>>>>>reference to a UI element in this chunk of code, and this is the
>>>>>>>>>specific line that throws the exception.
>>>>>>>>>
>>>>>>>>>Any ideas???
>>>>>>>>
>>>>>>>>--
>>>>>>>>Texeme
>>>>>>>> http://texeme.com
>>>>>>>>
>>>>>>
>>>>>>--
>>>>>>Texeme
>>>>>> http://texeme.com
>>>>>>
>>>>
>>>>--
>>>>Texeme
>>>> http://texeme.com
>>>>
>>>
>>>[/color][/color][/color]
--
Texeme http://texeme.com |  | Similar C# / C Sharp bytes | | | /bytes/about
We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights.
Get the best answers to your questions from over 226,449 network members.
|