Returning an IAsyncResult object?

  • Thread starter Thread starter deostroll
  • Start date Start date
D

deostroll

HI,

I know that if you want to write a method that does some operations
and you want to async execute it, you write a method with the
following pattern

IAsyncResult BeginOperation(AsyncCallback userCallback, Object state);

This is a simple prototype. Now inside this method how do I return an
IAsyncResult object if I use the classical methods of thread creation
(i.e. if I call the sync task with a Thread.Start())?

--deostroll
 
You have to create it yourself.  That is, write a class that implements 
the interface, and encapsulates whatever you need in order to connect the 
client who has a reference to the IAsyncResult implementor to your  
internal implementation.

Examples of things you might want to include in such a class would be an  
event handle you set when your asynchronous execution completes, a  
reference to the callback passed to you by the client, and a reference to 
the "state" object it passes as well.

Pete

Do u know any samples that can help?

deostroll
 
I know that if you want to write a method that does some operations
and you want to async execute it, you write a method with the
following pattern

IAsyncResult BeginOperation(AsyncCallback userCallback, Object state);

Hi,

Actually this functionality is built-in to delegates. If You have a delegate
You can invoke it async, without manually doing all of the threading.

Example:
// some delegate definition
public delegate int SomeDelegate();

// code
// this will be executed async
SomeDelegate d = new SomeDelegate(delegate()
{
for (int i = 0; i < 10; i++)
{
Console.WriteLine("delegate :" + i);
System.Threading.Thread.Sleep(500);
}
return 42;
});
// start async execution
d.BeginInvoke(new AsyncCallback(delegate(IAsyncResult result)
{
Console.WriteLine("Async call completed.");
int a = d.EndInvoke(result);
Console.WriteLine("Result of method is : " + a);
}
), null);
// do something on the main thread
for (int i = 0; i < 15; i++)
{
Console.WriteLine("main thread :" + i);
System.Threading.Thread.Sleep(300);
}
Console.ReadLine();


Hope You find this useful.
-Zsolt
 
Actually this functionality is built-in to delegates. If You have a delegate
You can invoke it async, without manually doing all of the threading.

Is this executed in the threadpool? (I mean if you use BeginInvoke()
via a delegate).

I want an idea as to what to code for if I implement IAsyncResult.
Coding for the AsyncState is ok; Usually all Begin methods will have a
state object passed to it, so I am guessing that is it. How do I code
for the other properties.
AsyncWaitHandle
CompletedSynchronously
IsCompleted

Thanx in advance

--deostroll
 
It is.


You have to create a WaitHandle that you set when the operation  
completes.  See ManualResetEvent for an example of an appropriate  
WaitHandle sub-class.  Return that handle from the property getter.

WaitHandles are expensive to create, and depend on relatively expensive OS  
objects.  So most implementors of IAsyncResult create the handle  
"lazily".  That is, they don't create it until someone actually calls the  
property getter.


If your async implementation never completes synchronously -- that is,  
before the Begin... method returns -- you can just always return "false"  
for this property.  Otherwise, you need to keep track of whether it's  
completed synchronously and return the appropriate value.


Maintain a boolean variable indicating whether the operation has completed  
or not.  Return its value from this property.

Of course, if you use the Delegate.BeginInvoke() method to implement your 
async pattern, you don't need to implement IAsyncResult at all.  Just  
return the IAsyncResult that BeginInvoke() returned.

You really should read the MSDN documentation on this topic.  http://msdn.microsoft.com/en-us/library/ms228969.aspx It's actually  
reasonably comprehensive.  Your questions about how to implement  
IAsyncResult would probably not need to be asked if you actually  
understood better how the async programming pattern in .NET works.

Pete

The Delegate.BeginInvoke() pattern of threading a task in my case is
not good. I guess this will utilize the threadpool. I've got
ThreadStatic members in some classes. That and using the thread pool
does not go hand in hand.

--deostroll
 
I have written something on my own. Actually I borrowed ideas from the
following blog:
http://blogs.msdn.com/ploeh/archive/2007/02/09/AGenericIAsyncResultImplementation.aspx

It shows a generic implementation. I got some vague ideas after
looking at that code. I am including a part of the code. I don't think
I've done things the right way, however I have sort of achieved my
purpose. (Ultimately not happy tho).

public class MasterTask
{
public MasterTask()
{

}
Thread task;
bool _Cancelled;
public bool CancelTask
{
get { return _Cancelled; }
set { _Cancelled = value; }
}

public IAsyncResult BeginTask(AsyncCallback userCallback,
object state)
{
MasterTaskAsyncResult mtasyncres = new
MasterTaskAsyncResult(new ManualResetEvent(false), userCallback);
task = new Thread(DoTask);
task.Start(mtasyncres);
return mtasyncres;
}

void DoTask(object AsyncHandle)
{
MasterTaskAsyncResult asyncResult = (MasterTaskAsyncResult)
AsyncHandle;
Random r = new Random();
int Limit = r.Next(30);
Console.WriteLine("Limit = {0}", Limit);
int i;
for (i = 1; i <= Limit; i++)
{
if (!this.CancelTask)
{
string status = "Doing task...";
int percent = Convert.ToInt32((i * 1f / Limit) *
100);
Thread.Sleep(1000);
double rate = 0;
if (TaskProgressChanged != null)
TaskProgressChanged.Invoke(this, new
TaskProgressChangedEventArgs(status, percent, rate));
}
}
asyncResult.Complete(null);
}

public void EndTask(IAsyncResult result)
{
task.Join();
}

public delegate void TaskProgressChangedEventHandler(object
sender, TaskProgressChangedEventArgs e);
public event TaskProgressChangedEventHandler
TaskProgressChanged;
}

--deostroll
 
Back
Top