Async service calls.

  • Thread starter Thread starter Graham Allwood
  • Start date Start date
G

Graham Allwood

I have a problem I need some help with. I am writing a Windows Forms
distributed app. I want my UI to be responsive so all calls to the business
objects which live in IIS I am calling asynchronously via a worker thread.

I have this all working but there are a couple of design / architecture
questions still hanging about. They are:

When making the async call I can keep the UI responsive but it leaves my
with different methods of getting the results out of the thread. I could use
a while loop testing the ThreadState, waiting for it to complete. Inside the
while loop I would call Application.DoEvents() and then Thread.Sleep(100).
The other way of getting the results would be by using a delegate for the
thread completion. The seconds option seems more elegant but is a little
harder to code. Is there a correct answer to my problem? Use a loop with
DoEvents or use a callback?

Can anyone help me please?

Regards

Graham
 
Thanks,

I think that answers my questions, however, it does raise another.

If I create my own user control I can make my public methods thread safe
(using InvokeRequired and Invoke), but is it possible to do the same with
properties, ie. Control.Enabled = false? I want to re-enable a control when
the async command completes.

At the moment it is looking as though I will have to implement public
properties with private methods that can be made thread safe.

Regards

Graham
 
Hi Graham,

Yes, same can be done with properties (meaning properties of the user
control). When doing so 'InvokeRequired' and 'Invoke' might still have to
used as the form that hosts the control may use it in a sync or async mode.

Regards,
Sankalp
 
You could try somthing like this, if the property corresponds to a UI
element. Have'nt tried this code snippet though !

public bool Enabled {
get {
if (this.InvokeRequired) {
}
else {
return this.Enabled;
}
} //get
set {
if (this.InvokeRequired) {
}
else {
this.Enabled = value;
}
}//set
} //Prop - Enabled

Regards,
Sankalp
 
But if InvokeRequired is true I see no Invoke() method call, am I missing
something?
 
Hi Graham,
You need to call Invoke when Invoke.Required is true (I've missed it out), I
have only shown how the structure/logic of would look like for your
understanding.

Regards,
Sankalp
 
Hi Graham,

Here some code that is more complete.Hope it helps.
This snippet compiles(have'nt tested it though)


delegate bool SafeGetEnabled();
/// This method should always run on the UI thread
private bool GetEnabled() {
return this.CEnabled;
}

delegate void SafeSetEnabled(object val);
/// This method should always run on the UI thread
private void SetEnabled(object val) {
this.CEnabled = (bool)val;
}

public bool CEnabled {
get {
if (this.InvokeRequired) {
//Call GetEnabled() on UI thread
SafeGetEnabled safeGet = new SafeGetEnabled(GetEnabled);
IAsyncResult apropres = this.BeginInvoke(safeGet);

while(!apropres.IsCompleted)
System.Threading.Thread.Sleep(100);

object propResults = this.EndInvoke(apropres);
return (bool)propResults;
}
else {
return this.Enabled;
}
} //get
set {
if (this.InvokeRequired) {
//Call SetEnabled() on UI thread
SafeSetEnabled safeSet = new SafeSetEnabled(SetEnabled);
this.Invoke(safeSet, new object[] {(object)value});
}
else {
this.Enabled = value;
}
}//set
} //Prop - Enabled


Regards,
Sankalp
 
Hi Sankalp,

thanks for the sample. This pretty much confirms what I thought. That is, yo
cannot call invoke on a property, the accessors for the property would have
to use some private methods.

Thanks again for your help.

Graham

Sankalp said:
Hi Graham,

Here some code that is more complete.Hope it helps.
This snippet compiles(have'nt tested it though)


delegate bool SafeGetEnabled();
/// This method should always run on the UI thread
private bool GetEnabled() {
return this.CEnabled;
}

delegate void SafeSetEnabled(object val);
/// This method should always run on the UI thread
private void SetEnabled(object val) {
this.CEnabled = (bool)val;
}

public bool CEnabled {
get {
if (this.InvokeRequired) {
//Call GetEnabled() on UI thread
SafeGetEnabled safeGet = new SafeGetEnabled(GetEnabled);
IAsyncResult apropres = this.BeginInvoke(safeGet);

while(!apropres.IsCompleted)
System.Threading.Thread.Sleep(100);

object propResults = this.EndInvoke(apropres);
return (bool)propResults;
}
else {
return this.Enabled;
}
} //get
set {
if (this.InvokeRequired) {
//Call SetEnabled() on UI thread
SafeSetEnabled safeSet = new SafeSetEnabled(SetEnabled);
this.Invoke(safeSet, new object[] {(object)value});
}
else {
this.Enabled = value;
}
}//set
} //Prop - Enabled


Regards,
Sankalp



But if InvokeRequired is true I see no Invoke() method call, am I missing
something?
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnforms/html/winforms06112002.asp
to
the thread. is
 
Back
Top