Print Page | Close Window

Wrapping background worker with OperationResult

Printed From: IdeaBlade
Category: Cocktail
Forum Name: Community Forum
Forum Discription: A professional application framework using Caliburn.Micro and DevForce
URL: http://www.ideablade.com/forum/forum_posts.asp?TID=3553
Printed Date: 05-May-2024 at 2:18am


Topic: Wrapping background worker with OperationResult
Posted By: JohnBloom
Subject: Wrapping background worker with OperationResult
Date Posted: 26-Jul-2012 at 7:36am
I am writing a WPF application to manage our server side processes. Some of those processes involve long running tasks like starting and stopping windows services and interacting with windows in general. Since I come from a silverlight background I am still making everything asynchronous. 

I was wondering if there was a way to wrap code that is synchronous in OperationResult so I can chain it in a coroutine. I know that a coroutine can do both synchronous and asynchronous but it is still running the synchronous task on the ui thread. I need some way to push it onto another thread but I would still like to call it like it is an async domain call.

yield return _ServiceCenterUnitOfWork.WindowsServiceDomain.StartService(serviceName, null, ShowError);

 Something like that.
-John


-------------
-John Bloom



Replies:
Posted By: mgood
Date Posted: 26-Jul-2012 at 10:47am
Glad you are doing things asynchronously in WPF. That's how it should be done, even though you have the option of doing it synchronously.
 
Yes, there is a way to do this. The "Cocktail Async Pack for VS 2012" defines AsOperationResult for Task and Task<T>. Assuming that you are not doing this in VS 2012 just yet, you can grab TaskFns.cs from Github and drop it into your project. Once there you can do the following:
 
yield return Task.Factory.StartNew(() => DoSomethingSynchronous()).AsOperationResult();
The same file also defines overloads for Task.OnComplete() and Task<T>.OnComplete() to do the onSuccess, onFail callbacks. So your StartService method would look something like this:
 
public OperationResult StartService(string serviceName, Action onSuccess, Action<Exception> onFail)
{
      return Task.Factory.StartNew(() => DoStartService(serviceName))
                     .OnComplete(onSuccess, onFail);
                     .AsOperationResult();
}
 
You can even return a value at the end from your task back the the UI thread. For example if you want to return true or false to indicate whether the service started or not, you can do that like this:
 
public bool DoStartService(string serviceName)
{
    ......
    return resultValue;
}
 
public OperationResult<bool> StartService(string serviceName, Action<bool> onSuccess, Action<Exception> onFail)
{
      return Task.Factory.StartNew(() => DoStartService(serviceName))   // This will now return Task<bool>
                     .OnComplete(onSuccess, onFail);
                     .AsOperationResult();
}


Posted By: mgood
Date Posted: 26-Jul-2012 at 10:52am
Actually I just realized you don't need .AsOperationResult after .OnComplete. OnComplete already returns an OperationResult or OperationResult<T>.



Print Page | Close Window