I think they both use PostMessage and Control.Invoke waits on event.
This difference is *almost* never makes a difference.

Dmitriy

Richard Blewett wrote:

Control.Invoke uses SendMessage internally and Control.BeginInvoke uses
PostMessage.

Regards

Richard Blewett
DevelopMentor



-----Original Message-----
From: Moderated discussion of advanced .NET topics. [mailto:ADVANCED-
[EMAIL PROTECTED] On Behalf Of John Davis
Sent: 01 March 2004 11:48
To: [EMAIL PROTECTED]
Subject: Re: [ADVANCED-DOTNET] Thread with message pump (UI thread)

Yes, Control.Invoke uses the message pump.  The message pump is the queue
you speak of.  I'm guessing the mechanism uses a PostMessage with a
WM_USER
+ x.

----- Original Message -----
From: "John Elliot" <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Monday, March 01, 2004 5:34 AM
Subject: Re: [ADVANCED-DOTNET] Thread with message pump (UI thread)




If the UI never accesses the model directly (which would require


locking


to avoid possibly getting inconsistent data if the model is in the


process


of being updated), but only sends requests (via BeginInvoke) to the


model


thread for information, does that solve the problem?


I'm not sure that you can 'BeginInvoke onto the model thread'. As I
understand it (please correct me if I'm wrong), if I have a delegate I
can call BeginInvoke and it will be serviced by a worker thread from the
thread pool. I'm not sure that a 'worker thread from the thread pool' is
synonymous with 'model thread'.

There are some gaps in my understanding around this however. For
example, how is it that Control.BeginInvoke allows the delegate to find
its way into the code path on the UI thread? The delegate must be added
to a queue and serviced at some point right? Which queue? Does it use
the message pump? If so, what sort of message does it send? Where can I
read about the mechanics of Control.BeginInvoke?

The way I'm trying to think about it at the moment is that I have two
main threads. The 'UI thread' and the 'application thread'. The UI
serves two purposes:

1. Represent the model (view)
2. Command the model (controller)

My goal is to keep the UI as free as possible, basically the only
reasons for this are so that it can paint, respond to user requests that
don't rely on the model, or to 'cancel' something that is in progress.
It seems that a massive amount of work needs to be done to achieve these
relatively humble goals.

The reason that this is hard in my particular case is that I have an MDI
WinForms application that shares data from a local (in-process) 'model'
of the data from the database. I don't use Dataset etc. because I run
into all sorts of trouble with a user fighting *with themself* over read
locks (i.e. timestamp/rowversion), defining complex relationships
between data that hasn't been allocated a primary key, etc. I use my own
business objects and collections to help me manage these relationships,
basically I'm building my own object-relational wrapper that is the main
component of the 'Model' in my MVC application.

There are a few hairy design challenges. I want my model to be equally
usable in both a web based and WinForms based application. It gets
pretty challenging though, because the 'model' is designed for 'client
side' representation of data (I have a stateless application server that
can service requests and commands to populate the client-side model or
persist it to a data store) and these two execution contexts are quite
different.

In a web based app, multiple users share a process, and if two users
were editing the same domain object (say, Employee, Invoice, etc.) then
I'd let them do it, and fail with an optimistic concurrency error ASAP
(to avoid them wasting their time). A web based app is largely
request-response, and so is simple in this regard. The user takes a read
lock (in the virtual, optimistic concurrency sense) on a 'smallish'
amount of data and then submits changes to that data, assuming there has
been no resource contention during the period that they were editing the
data I can just apply their changes, otherwise I can take them into a
'merge' process (heh, or fail them ;). Obviously, pessimistic
concurrency has a whole heap of problems (particularly with a web based
system) so I choose optimistic concurrency as the lessor of two evils.

But an MDI WinForms app is quite different because it offers a more
sophisticated UI. In a windows based app, if I have the same domain
object open in two views, and I alter one view, then I don't want:
A. the other view to continue displaying stale data
B. the user to have a concurrency problem when they flip to the other
view later and make an edit (to the now stale data)

I'd really like my business model to be resilient in the face of
'disconnection' too. So a user can carve off some existing data, enter
new data, specify complex relationships, and pump it all back into the
live system much later. I'd like to get as much support for this into
the business model (and related APIs) as possible, but this is largely
beside the point at the moment.

I've already dealt with a lot of these problems, and I'm pretty happy
with what I've got (it's too complex for me to really go into via this
e-mail).

I would describe what I have client-side in my MDI WinForms application
as an MVC application. I know that people argue about what MVC is, and
have different ideas about it. The scope of the problem that I'm trying
to describe here though, is that given this 'static' client-side model:
reading from it, updating it, etc. is all (relatively) straight forward
if all my processing happens synchronously on the UI thread. The problem
is that the UI thread is not free to respond to the user or paint itself
while it is processing, such processing pretty much always involves
going over the wire to the application server with blocking requests for
state or commands to change state (basically the CRUD).

One of the particularly challenging problems is that 'View' code often
needs to do more than just 'read' from the model, often it needs to
'load' data into the model, and this is a long-running process.
Lazy-loading isn't an option if I don't want to block the UI thread, and
really is 'programming by side-effect', because I can affect the state
of the model by doing a read operation. Design challenges are further
aggravated by security, caching, etc.

At the moment I'm really looking at how I can use a different kind of
messaging paradigm between the Model/View/Controller than I presently
have. At the moment such messages are passed using multicast delegates
(AKA events). The crux of the problem with this type of notification is
that the message is sent synchronously as it happens. So, I'm leaning
more towards a client/server type of messaging system (more like
publish/subscribe than 'observer' if it's fair to try and make such a
distinction) where I can queue the multicast delegate for invocation
later, rather than dispatch it immediately.

What I'm finding is that I now need to maintain 'message and command
queues' that are serviced on the appropriate thread. For example, if
code executing on the 'application thread' causes a change in state to
the model that a view has registered interest in (by attaching an event
handler) then rather than synchronously invoking the event so the view
can be updated immediately, I'd like to place this event on a queue so
that once the processing on the 'application thread' runs to completion
and the model is returned to a 'consistent' and 'not-locked' state I can
dispatch all the messages on this queue on the UI thread and let the
View objects request the updated state from the appropriate parts of the
model (with no fear of the model either being locked or in an invalid
state). Interestingly, it seems that I also need a queue for queuing
long-running commands (like 'Save') triggered by the user (or an event)
on the UI thread for processing on the application thread. Then I need
some form of mutex that ensures that either the 'controller queue' is
being serviced XOR the 'view event queue' is being dispatched. Meaning
really that either the UI thread is reading from the model, or the
application thread is updating it, but neither can attempt to run at the
same time. On the face of it, this seems like the best way to go at the
moment, but perhaps this is a crazy idea?



The UI thread will update the display using information passed in


event-


handler parameters (as you indicated was a possibility), or it can use
BeginInvoke to send a request for model state to the model thread and


uses


the results that (eventually) come back to update the display.  (The
latter could happen if the user pressed a Refresh button, or expands a
tree node whose contents only exist in the model, or some such.)  If


the


user does something in the UI that should cause an update to the


model,


the UI thread uses BeginInvoke to pass the "update model" request.


The 'pass state with event args' problem is interesting. Initially it
seems like this might be valid, but after a while you realise that (as
Shawn pointed out in his last post on this thread) you really need to
'clone' state objects that are not strictly 'atomic' or 'immutable' when
you do this. Once you start adding any degree of complexity, then this
can get completely out of control and you might have to clone thousands
of objects just so you could send a Client.ProjectChanged event. If it
was just Client.NameChanged I might be able to pass a string with the
new name in the event args, but if the 'property' that changed was a
related business object then I might have to clone it (and everything
that it contained) just to pass the event. If the UI then wanted data
from this cloned Project that had not yet been loaded, it would have to
query the application server for that data. Basically my entire goal is
to 'avoid cloning, at all, ever' on the client-side, because it can
really hurt the working set, but more particularly because once I clone
I have one user with duplicate read locks on the same data that they can
cause to become stale. My other goal is to 'avoid locking, at all, ever'
because saving myself from deadlocks is non-trivial, locking decreases
performance, and I can still end up blocking the UI thread. Usually the
solution to avoid one is to do the other, but I don't want to do either.
Like I said, I want to have my cake and eat it too! :)

The only way that I can see to accomplish this, is to have a 'turn
based' system, where the UI thread has a go at reading changes, painting
itself and queuing commands, then the application thread has a go at
processing the command queue, updating the model and queuing
notifications for the UI. The UI can still do 'stuff' while the
application thread is executing, but it must guarantee not to touch the
model. I haven't hit the point where this gets unreasonable yet, but so
far it's only in my mind (no concept code or anything like that) so
there may be some complexity that this introduces that is beyond my
ability to address that I haven't stumbled across yet (if there is, it
will most likely be with the 'controller' side of the problem, because I
haven't had a close look into that yet).

The reason that I need a 'client-side' model is that I don't want
'temporary state' to be maintained on behalf of clients by the
application server. Say I have a scenario where I'm entering a new
'Employee'. I client the 'Create new Employee' button, and up pops a
form. Behind the scenes there some code specified 'new Employee();' as
the data source on this form. The user enters the name etc, but wants to
add an 'Address' for the residential address. Given that the residential
address is now not going to be 'null' I create a 'new Address();' and
assign it. Now I'm starting to have complex 'temporary state' in the
client that will need to be persisted by the application server inside a
single transaction. If I then specified that this employees postal
address 'was the same as their residential address' I might do something
like this: this.Employee.PostalAddress =
this.Employee.ResidentialAddress; Now things are getting even tougher,
because not only have I got complex relationships that I need to model
without primary keys that will later be specified by application server
(or the database) but I also have to represent this change to the user
in the user interface. So, if I had two 'AddressControl' instances that
represented the Residential and Postal address for this Employee on the
'EmployeeControl' then if I changed the residential address I'd want to
see this change reflected in the postal address control. This is a
simple (and perhaps silly example) but it outlines the complexity that
I'm trying to model, and should serve to demonstrate why I can't
maintain the 'model' on the application server as easily as I can on the
client.

Anyway, that's my rant for the day. At the end of the day the way I look
at it is that the MVC pattern (or perhaps I should say 'observer' or the
event-driven paradigm) is as old as time, async programming is as old as
time, and what I want is some good material where someone discusses
methods of integrating the concepts of each. I don't really want
asynchronous execution, what I really want is a method of keeping my UI
responsive while I work on shared local data, it's just that async
programming seems to be what I need to do to achieve this end. That's
way I'm happy to simply have the 'two main threads' and just managed
requests and notifications via queues. Obviously, in trying to do this,
a whole lot of things need to be taken into consideration, and
responsibilities and contracts need to be given to various components,
I'm trying to figure out what those should be, but if someone has
already done the work, I'd rather save myself some trouble.. :P

Perhaps I should get myself a book on 'game programming'. Those guys
have been doing stuff like this for years right?

The facilities in .NET alone at the moment are not of themselves
sophisticated enough to allow me to do everything that I want to do, so
I really need an application framework on top of .NET to help me.

Obviously there are applications that work this way. Consider how VS.NET
works. If I have a class open in the code editor and change the class's
name, then the name change is reflected in the drop-down list on the
top, left and in the Class View. There is a slight delay in the UI being
updated however, and my keystrokes aren't delayed while the UI updates
itself (I think, I could be wrong about that), indicating that this
'event' has been queued and dispatched. Basically I want to know about a
pattern for accomplishing functionality like that. Is it simply the case
that they are using WM_PAINT, and invalidating the control? If so, then
what is the UI thread going to do when it wants the current value for
the class name? Lock the business model of the Class so that it can read
out the name value, meaning that the code editor needs to acquire the
same lock when updating? I'm sure that because of all the parsing, etc
that would be required this software is *far* more sophisticated that
what I'm trying to achieve, but there are elements of a similar pattern
that must have been addressed here right? If I was to run a 'find and
replace' operation, then I wouldn't want my code to alter the code
editors text box, but rather the 'compile unit' or 'source file'
business object, then have the changes reflected in the text box (the
view). My system is not a text editor of course; it's basically a
glorified database browser.

Should I just give in and leave all my code on the UI thread? The
reality is that in a 'typical' usage scenario the UI locks up for much
less than 500ms during an operation, but this still sucks right? In my
travels I've never seen any software adequately deal with all of these
problems.

John.

===================================
This list is hosted by DevelopMentor®  http://www.develop.com
Some .NET courses you may be interested in:

NEW! Guerrilla ASP.NET, 17 May 2004, in Los Angeles
http://www.develop.com/courses/gaspdotnetls

View archives and manage your subscription(s) at


http://discuss.develop.com

===================================
This list is hosted by DevelopMentor®  http://www.develop.com
Some .NET courses you may be interested in:

NEW! Guerrilla ASP.NET, 17 May 2004, in Los Angeles
http://www.develop.com/courses/gaspdotnetls

View archives and manage your subscription(s) at
http://discuss.develop.com

---
Incoming mail is certified Virus Free.
Checked by AVG anti-virus system (http://www.grisoft.com).
Version: 6.0.593 / Virus Database: 376 - Release Date: 20/02/2004




--- Outgoing mail is certified Virus Free. Checked by AVG anti-virus system (http://www.grisoft.com). Version: 6.0.593 / Virus Database: 376 - Release Date: 20/02/2004


=================================== This list is hosted by DevelopMentor® http://www.develop.com Some .NET courses you may be interested in:

NEW! Guerrilla ASP.NET, 17 May 2004, in Los Angeles
http://www.develop.com/courses/gaspdotnetls

View archives and manage your subscription(s) at http://discuss.develop.com





===================================
This list is hosted by DevelopMentor®  http://www.develop.com
Some .NET courses you may be interested in:

NEW! Guerrilla ASP.NET, 17 May 2004, in Los Angeles
http://www.develop.com/courses/gaspdotnetls

View archives and manage your subscription(s) at http://discuss.develop.com

Reply via email to