Note that there are some explanatory texts on larger screens.

plurals
  1. POMaking an operation asynchronous
    primarykey
    data
    text
    <p>I have a big application that implements some services, the interface it uses is </p> <pre><code>IResult Execute(IRequest) </code></pre> <p>Its all wrapped inside an IHttpHandler. Some of these services use a common infrastructure component I want to replace. The problem is, my component takes long time to run, and since all this is hosted inside an IIS server it will very quickly exhaust its worker threads.</p> <p>I can wrap the services inside an IHttpAsyncHandler, but I still need a way to use my component asynchronously, other wise I'll just be holding a different worker thread.</p> <p>I of course can just execute my service inside it's own thread, but it's very expensive. using System.Threading.Tasks.Task or Delegate.BeginInvoke, would just hold up another thread or worker thread, depending on implementation. </p> <p>Ideally, I would like if I could, when my long running operation is called, take the thread's stack, and execution context, save them aside, start doing my work (which is mostly IO and asynchronous by itself), release the thread im using to the thread pool\ OS, and when done take the context I saved aside and continue execution with my result.</p> <p>This is very possible in some functional languages or when using continuation, how can it be achieved in C#?</p> <hr> <p>After doing some research, I think what I need to do, is a sort of continuation. I need to freeze my current execution thread stack, release the thread back to the pool, and restart the frozen stack, on the callback from the async operation I'll be using.</p> <hr> <p>To Justin Pihony's request I'm adding some code to better describe my problem.</p> <p>This is my Http Handler (a simplification of course):</p> <pre><code>class Handler: IHttpAsyncHandler { private readonly Action&lt;HttpContext&gt; _processDelegate = ProcessRequest; public void ProcessRequest(HttpContext context) { IBuissnessService blThing = IOC.Get(context.Something); // usually doesnt take too long... thing.DoWork(context); } public bool IsReusable { get { return true; } } public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData) { return _processDelegate.BeginInvoke(context, cb, extraData); } public void EndProcessRequest(IAsyncResult result) { _processDelegate.EndInvoke(result); } } //this is the buissness object class BLThing :IBuissnessService { public void DoWork(HttpContext) { //.... a Lot of Stuff // in some point one of the objects this is using does: IDoWork someObject = IOC.GetSomthing(); var result = someObject.DoWork(); // uses the result some more // and eventually returns. } } class SomeObject : IDoWork { public Result DoWork() { // does some very long http call to another server } } </code></pre> <p>I can't change "BLThing" but I fully control "SomeObject " also eventually i need to support the same interface "BLThing" expects.</p> <p>I want to add to "SomeObject" two async methods (BeginDoWork, EndDoWork) and write:</p> <pre><code>class SomeObjectWrapper : IDoWork { SomeObject _worker ; public Result DoWork() { worker = new SomeObject(); ThreadState state = CurrentThread.CaptureState(); worker.BeginDoWork(Callback,state) CurrentThread.PurgeStateAndReturnToPool(); } void Callback(IAsyncResult result) { var processingResult = worker.EndDoWork(result); ThreadState state =(ThreadState) result.AsyncState; state.ReturnTopCall(processingResult); CurrentThread.RestoreThreadState(state); } } </code></pre> <hr> <p>Well in .Net doing this is not possible. Actually it is, but would require a lot of work, and probably won't give any performance benefit over create a full blown thread. an approach like this will be beneficial only in a language (or platform) that is much more functional in nature, and has a memory and threading model rather different then the one Win-API is using.</p> <p>Although if one initially writes his code in an asynchronous manner, or relies on the TPL, he could probably achieve this quite easily...</p> <p>I'm awarding the bounty to Justin, if not for the answer then for the discussion.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload