PC Review


Reply
Thread Tools Rate Thread

invoking on the UI thread

 
 
Stefan Ram
Guest
Posts: n/a
 
      4th Jun 2012
I read »The only thread that's allowed to directly access a
property value of a form or one of its controls is the
primary UI thread« (in
http://msdn.microsoft.com/en-us/magazine/cc188732.aspx).

Is there a method in the standard library that I can call to
have a method/delegate/lambda of mine be executed on this UI
thread, preferably with a priority lower than user generated
events (so that the UI thread first handles user inputs,
then calls my method when it would have become idle
otherwise)?

(If someone knows Java: I am searching for a possible
equivalent of Java's »invokeLater« method of the Java
standard library, tha is
http://docs.oracle.com/javase/7/docs....lang.Runnable)
.)

 
Reply With Quote
 
 
 
 
Tom Shelton
Guest
Posts: n/a
 
      4th Jun 2012
Stefan Ram expressed precisely :
> I read »The only thread that's allowed to directly access a
> property value of a form or one of its controls is the
> primary UI thread« (in
> http://msdn.microsoft.com/en-us/magazine/cc188732.aspx).
>
> Is there a method in the standard library that I can call to
> have a method/delegate/lambda of mine be executed on this UI
> thread, preferably with a priority lower than user generated
> events (so that the UI thread first handles user inputs,
> then calls my method when it would have become idle
> otherwise)?
>
> (If someone knows Java: I am searching for a possible
> equivalent of Java's »invokeLater« method of the Java
> standard library, tha is
> http://docs.oracle.com/javase/7/docs....lang.Runnable)
> .)


I am going to assume windows forms. Control.Invoke. All windows forms
and controls inherit from control.

Alternatively, if your threading needs are not to complex - look at the
backgroundworker control. It can often eliminate the need for explicit
threading and ui syncronization.

--
Tom Shelton


 
Reply With Quote
 
 
 
 
Stefan Ram
Guest
Posts: n/a
 
      4th Jun 2012
Tom Shelton <(E-Mail Removed)> writes:
>I am going to assume windows forms. Control.Invoke. All windows forms


But AFAIK Control.Invoke is synchronous, I want something like this:

Public Sub ExampleMethod()
Call DoSomethingOnTheUserInterface()
InvokeOnTheUIThreadLater( New Example( AddressOf ExampleMethod ))
End Sub

What this is intended to do is the following (think of a
game or animation loop):

1. DoSomething on the user Interface
2. process any pending user input
3. when there is no more pending user input, repeat at step 1

The above method is intended to achieve this by

1. Call DoSomethingOnTheUserInterface
2. register itself to be called later, when there are no
more other events pending
(Now the system has time to process any pending user
input and other events. When it is done, it will call
ExampleMethod again, so we will be at step »1.«, again.)

Effectivly, I want a method of mine to be called, when the
program is »idle«, i.e., when there are no more pending
events to be processed.

 
Reply With Quote
 
Tom Shelton
Guest
Posts: n/a
 
      4th Jun 2012
Stefan Ram was thinking very hard :
> Tom Shelton <(E-Mail Removed)> writes:
>> I am going to assume windows forms. Control.Invoke. All windows
>> forms

>
> But AFAIK Control.Invoke is synchronous,


It is... But, there is an async version - Control.BeginInvoke paired
with Control.EndInvoke.


> I want something like
> this:
>
> Public Sub ExampleMethod()
> Call DoSomethingOnTheUserInterface()
> InvokeOnTheUIThreadLater( New Example( AddressOf ExampleMethod ))
> End Sub
>
> What this is intended to do is the following (think of a
> game or animation loop):
>
> 1. DoSomething on the user Interface
> 2. process any pending user input
> 3. when there is no more pending user input, repeat at step 1
>
> The above method is intended to achieve this by
>
> 1. Call DoSomethingOnTheUserInterface
> 2. register itself to be called later, when there are no
> more other events pending
> (Now the system has time to process any pending user
> input and other events. When it is done, it will call
> ExampleMethod again, so we will be at step »1.«, again.)
>
> Effectivly, I want a method of mine to be called, when the
> program is »idle«, i.e., when there are no more pending
> events to be processed.


I'm not exactly clear on what you are trying to accomplish. Using your
example of a game loop - that would typically look something like
(total pseudocode here - and ignoring the whole game clock thing):

while (running)
UpdateGame () ' update the internal game state
DisplayGame() ' update the user interface
end while

Uusally, the udpategame would process input that has occured since the
last tick, calculate positions, etc. And then, you would render the
current state to the ui. Assuming your game loop is on another thread
(which, would be unusual) - you would almost certainly want any of your
calls to update the ui state to be synchronous anyway.

So, can you be a little more clear about what your trying to accomplish
and where the trheading is actually comming into play?

--
Tom Shelton


 
Reply With Quote
 
Stefan Ram
Guest
Posts: n/a
 
      4th Jun 2012
Tom Shelton <(E-Mail Removed)> writes:
>while (running)
> UpdateGame () ' update the internal game state
> DisplayGame() ' update the user interface
>end while
>
>Uusally, the udpategame would process input that has occured since the
>last tick, calculate positions, etc. And then, you would render the
>current state to the ui. Assuming your game loop is on another thread
>(which, would be unusual) - you would almost certainly want any of your
>calls to update the ui state to be synchronous anyway.
>
>So, can you be a little more clear about what your trying to accomplish
>and where the trheading is actually comming into play?


I was just not aware that one can program this way in VB.

You say »udpategame would process input«. How do I do this in VB?
»udpategame would process input« sound as if the program would query
(read) the user input, while AFAIK in VB one instead defines subs such as

Sub Command1_Click()
...
End Sub

which are called by the UI thread whenever appropriate.

I used to think that a loop such as:

>while (running)
> UpdateGame () ' update the internal game state
> DisplayGame() ' update the user interface
>end while


need to run in the UI thread, since it is updating the UI,
but then, it will block the processing of events as long as
it is running, since there is only one UI thread and this is
currently busy executing this loop. So what do you do to
»process input« within this loop, when it actually needs to
terminate for input to be processed in the single UI thread?

 
Reply With Quote
 
Tom Shelton
Guest
Posts: n/a
 
      5th Jun 2012
Stefan Ram was thinking very hard :
> Tom Shelton <(E-Mail Removed)> writes:
>> while (running)
>> UpdateGame () ' update the internal game state
>> DisplayGame() ' update the user interface
>> end while
>>
>> Uusally, the udpategame would process input that has occured since
>> the last tick, calculate positions, etc. And then, you would
>> render the current state to the ui. Assuming your game loop is on
>> another thread (which, would be unusual) - you would almost
>> certainly want any of your calls to update the ui state to be
>> synchronous anyway.
>>
>> So, can you be a little more clear about what your trying to
>> accomplish and where the trheading is actually comming into play?

>
> I was just not aware that one can program this way in VB.
>
> You say »udpategame would process input«. How do I do this in VB?
> »udpategame would process input« sound as if the program would
> query (read) the user input, while AFAIK in VB one instead defines
> subs such as
>
> Sub Command1_Click()
> ...
> End Sub
>
> which are called by the UI thread whenever appropriate.
>
> I used to think that a loop such as:
>
>> while (running)
>> UpdateGame () ' update the internal game state
>> DisplayGame() ' update the user interface
>> end while

>
> need to run in the UI thread, since it is updating the UI,
> but then, it will block the processing of events as long as
> it is running, since there is only one UI thread and this is
> currently busy executing this loop. So what do you do to
> »process input« within this loop, when it actually needs to
> terminate for input to be processed in the single UI thread?


It seems we are talking about the render loop for a game. I'm not a
games programmer, by any streatch of the imagination - but, it's
something I have played with a bit. Personally, if I were you - I
would look into using XNA for your game needs - but, I'm not sure of
the level of VB support currently. I'm basically a C# guy... XNA will
handle a lot of the plumbing of the basic render loop, i/o, resource
handeling, etc. So, it might be worth it to look into it.

That, said - I'll try to give you a couple of basic options if your
talking windows forms/gdi+ style games, at least the ones I've used

1) In some case simple windows forms timer can be sufficient depending
on how precise your timeing needs to be (if I remember correctly, a
windows forms timer can be +-100ms or so). You can just set your timer
up in the load event (or as I do, I usually encapsulate all of this
into a game class - but, I'm just trying to keep it simple):

GameTimer.Enabled = True
GameTimer.Interval = 1000/ FRAMES_PER_SECOND ' CALCULATE THE DESIRED
INTERVAL


Then you just handle your game stuff in the tick event:

Sub GameTimer_Tick (ByVal sender As Object, ByVal e As EventArgs)
Handles GameTimer.Tick

' handle your game state udpate and drawing here
End Sub

2) Use an api based timer if you need more percision. Other than
that, it's similar to above except you have to make use of p/invoke
I can help you with that if you go this route.

3) use a render loop with Application.DoEvents() - this my fav

Again, I tend to encapsulate a lot of the game into a class. I have a
in progress version of the old basic gorilas game that i've been
tinkering with from time-to-time. My main method looks like this (this
is C#, but, the VB code wouldn't be all that different:

static void Main ()
{
Application.EnableVisualStyles ();
Application.SetCompatibleTextRenderingDefault ( false );

// show the form and start the game loop
using ( GorillaForm gorillaForm = new GorillaForm () )
{

GorillaGame = new Game ( gorillaForm );
gorillaForm.Show ();
while ( !GorillaGame.GameOver )
{
GorillaGame.Render ();
Application.DoEvents ();
}
}
}

Basically, that lets the loop run as fast as it can - and still window
messages are processed (Application.DoEvents()). Basically, the
GorillaForm is nothing but a blank form with some default settings
(fixed border, etc). The game class hooks all of the input events,
etc, and handles them.

I'm not endorsing any particular method - but, the point is that you
probably don't need to worry about threading and syncronization, if
this is just a typical game app?

--
Tom Shelton


 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
ShowDialog - Cross-thread operation not valid: Control'CheckAccountInfo' accessed from a thread other than the thread it was createdon. Tom C Microsoft C# .NET 9 20th Feb 2008 09:15 PM
Invoking a method from the main thread, from a worker thread. DaTurk Microsoft C# .NET 6 30th Aug 2007 08:07 PM
Cross-thread operation not valid: Control '' accessed from a thread other than the thread it was created on Joe Microsoft C# .NET 4 12th Mar 2007 10:59 AM
Thread A calls a delegate on Thread B but Thread A executes it!?!? Paul Tomlinson Microsoft C# .NET 4 3rd Feb 2005 11:09 PM
Shut down thread - thread closes form, form doesn't close because thread calls it etc... Robin Tucker Microsoft VB .NET 4 17th Oct 2003 12:03 PM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 07:00 AM.