Or you may want to take a look at Microsofts asynchronous application
block

>> multithreaded MVC in WinForms

MVC (Model View Controller) comes from Smalltalk and is a pattern for
decoupling view, controller and application model. In ASP.NET for
example the code behind file is the controller, .aspx (with only render
code) is the view and the model is what ever you want it to be. Often
the controller and view are implemented as the same class - WinForm
implementation
Another pattern usually used with MVC is the observer
(publish/subscribe) pattern which enables the model to inform the views
of changes. When used with MVC the model is the subject and the view is
the observer. The observer provides an implementation of an Update
function which the subject then calls. So, the idea is when the model
changes any views subscribed will be notified via their Update methods.
This pattern was used in MFC (yuck!) - may remember it being called DDX,
DDV.

Some catalogues say that the Update method of the observer should accept
a subject as one of the parameters. Whilst I don't disagree with this I
do think it can be misleading. In a multithreaded environment it could
be a potential disaster to pass a reference to the model (the subject).
An alternative to passing a reference to the model is to use a push
replication strategy. Here the model calls Update of the observer, but
passes the 'changed' data 'by value' (a message). The view can then
decide which bits it needs. This is easier than a pull model (reference)
where the view would have to go get the data from the 'thread-safe'
model  

> I'm entertaining is that rather than invoking the events, I just
> >stash the event delegates on a FIFO queue and then dispatch them all
> >once the worker thread returns (in the UI thread on EndInvoke for

Combining delegates together would give you this functionality. If you
define your delegate with byRef parameters each delegate will be able to
modify the data. This is quite useful if you need to pass data from one
method to another in a chained manner (synchronously) - chain of command

> >    this.Name = GetNameFromWebService(this.Id);
> >    this.Phone = GetPhoneFromDatabase(this.Id);

Never, never do this type of stuff in a distributed application - if
you're an OO purist I apologize, but put simply don't extend OO thinking
when it comes to remote communication.
Fine granular calls like this are the killers are all applications (okay
blame RPC!), but if you take the same thinking that good OO design means
lots of getters and setters - forget it. It won't scale. In remoting
situations we place a course grained interface 'remote façade' onto the
remote object. This interface has methods like GetPerson, SetPerson etc

I know this is just an example that you're using (so I don't mean to
rant at you personally ;-)

A

> -----Original Message-----
> From: Moderated discussion of advanced .NET topics. [mailto:ADVANCED-
> [EMAIL PROTECTED] On Behalf Of J. Merrill
> Sent: 27 February 2004 14:28
> To: [EMAIL PROTECTED]
> Subject: Re: [ADVANCED-DOTNET] Thread with message pump (UI thread)
> 
> I'm not certain that I understand your situation completely, but I
don't
> see any issues that wouldn't be handled by using BeginInvoke rather
than
> Invoke.  That will let both UI and process threads proceed without
waiting
> on the other.
> 
> In some cases, you might want to use the FireAndForget mechanism
described
> at and available from
>     http://www.bearcanyon.com/dotnet/#FireAndForget
> 
> Good luck.
> 
> At 06:09 AM 2/27/2004, John Elliot wrote
> >> Oh, and the Tablet PC's Ink API fires some events on background
> >threads...
> >> Go figure, eh?
> >
> >Firing events from background threads for consumption in the UI is
the
> >hardest problem (for me) that I face at the moment.
> >
> >If I have a long running process that needs to invoke events that the
UI
> >has hooked then if I run this in a worker thread and trigger the
events
> >the event handlers will execute on the worker thread before
continuing.
> >This worker thread is not allowed to update the UI, so I have to
invoke
> >onto the UI thread in the event handler. After I invoke onto the UI
> >thread I can't call into the model for the state that I need to
render,
> >because the worker thread may have locked the model which would cause
> >the UI thread to block while waiting for its state.
> >
> >There are only two solutions that I can see. Have my business model
> >throw immutable state objects with the event (i.e. EventArgs), or
have
> >the business model queue events and dispatch them on the UI thread
when
> >the worker thread has run to completion.
> >
> >For example, say I have a thread safe Person class like this (in
pseudo
> >code):
> >
> >public Person {
> >  public int Id { get; }
> >  public event NameChanged;
> >  public string Name { get; set; }
> >  public event PhoneChanged;
> >  public string Phone { get; set; }
> >  public void SyncWithDatastore(
> >    this.Name = GetNameFromWebService(this.Id);
> >    this.Phone = GetPhoneFromDatabase(this.Id);
> >    // etc.
> >  )
> >}
> >
> >If SyncWithDatastore() has to hit say a few disparate datasources,
say
> >one via a WebService and another in ActiveDirectory or a DB or
> >something, then this could be a long running process, particularly if
> >there is a problem that waits for a timeout.
> >
> >If I call SyncWithDatastore() from the UI thread then the NameChanged
> >event would fire, then the PhoneChanged event and this would be fine
and
> >could be handled along the way on the UI thread, the problem is that
the
> >UI thread is blocked until the method completes.
> >
> >If I fire it on a worker thread, then the event handlers execute on
the
> >worker thread, if I invoke these onto the UI thread I can't then have
a
> >handler like this:
> >
> >void HandleNameChanged() {
> >  this.Text = this.Person.Name;
> >}
> >
> >because calling into the Person.Name getter may cause the UI to block
> >(assuming it is thread safe, if it's not thread safe then this would
be
> >a really bad idea anyway).
> >
> >So I'm really trying to figure out a way that I can have my cake and
eat
> >it too. I don't really want to create a business model that throws
state
> >with its events, because I'd be uselessly creating objects in
scenarios
> >where my business objects don't need to run in a thread safe manner,
I
> >guess too because I've never seen anyone else do this. :P The other
idea
> >that I'm entertaining is that rather than invoking the events, I just
> >stash the event delegates on a FIFO queue and then dispatch them all
> >once the worker thread returns (in the UI thread on EndInvoke for
> >example), this second option is kind of attractive, because it is
more
> >'atomic' in the sense that if I fail half way through I can decide
> >whether I want to dispatch the events or not, etc. (although that
seems
> >like it might start getting really complicated).
> >
> >I guess for this simple example, the properties wouldn't be locked
for
> >very long at all, so maybe it is OK to just invoke the event onto the
UI
> >thread and then read out of the model, assuming that it probably
isn't
> >locked and if it is it won't be for long. But some processes would
lock
> >for longer. Say for example (and this may be a really poor example,
or a
> >bad thing to do) I had another business object that had hooked the
> >PhoneChanged event for some reason, and this event was going to run
on
> >the worker thread, say the first event the worker thread fires is for
> >the UI control, then as it is invoked onto the UI it races the
> >invocation of the next handler, if the next handler wins, it might
run
> >some long running process and the UI is now blocked. Or perhaps not,
if
> >the events are invoked outside the critical section.. at any rate,
this
> >problem has still got my mind in knots.
> >
> >I haven't seen anything that I've really groked wrt to these ideas.
Does
> >anyone have any thoughts on this, or know where I can find some good
> >material?
> >
> >Basically: multithreaded MVC in WinForms.
> >
> >John.
> 
> 
> J. Merrill / Analytical Software Corp
> 
> ===================================
> 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