Derik Whittaker



Using TPL to access Async WCF Endpoints in MVC

I am in the process of building out a internal portal/dashboard for our company which will allow us to get a status of what is going on behind the scenes in our application.  I want this site to utilize our existing WCF endpoint and as much existing code as possible.  When doing this I realized pretty quickly that I needed to create Async Controller actions to hit our async endpoints which was a first for me.  Of course the first thing I did was a quick Bing search to see if I could find some existing examples to help me a long.  However, every example I found assumed that we were using the automatically generated proxy to access our endpoints rather than spinning up the connection manually via ChannelFactory and the service interface.  Because I struggled to get this working I thought I would share my experiances in case others are having the same issue.

Our WCF Endpoint Definition

    public interface IScheduledEventsService
        [OperationContract(AsyncPattern = true)]
        IAsyncResult BeginScheduledEvents(ScheduledEventsRequest request, AsyncCallback callback, object state);
        Result<IList<ScheduledEvent>> EndScheduledEvents(IAsyncResult result);


One thing to point out about the code above, the actual return value from our endpoint is a Result<T>.  The result class is a simple container envelope which provides us back some metadata, this is not something to worry about or to try to find online, you can simply ignore this for your needs

My MVC controller definition

public class ScheduledActivitiesController : AsyncController
        public Task<PartialViewResult> Listing()
            return Task.Factory
                .StartNew(() => GetScheduleActivitiesAsync())
                .ContinueWith(x => PartialView("_Listing", x.Result.ToList()));

        private IList GetScheduleActivitiesAsync()
            var baseUrl = ConfigurationManager.AppSettings["BaseWcfServerUrl"];

            var channel = ChannelHelper.CreateFor<IScheduledEventsService>(baseUrl);

            var myTask = Task.Factory
                           new Func<IAsyncResult, Result<IList<ScheduledEvent>>>(channel.EndScheduledEvents),
                           new ScheduledEventsRequest(), 

            var taskResult = myTask.Result;

            return taskResult.ResultItem;            

The above code is our entire controller (well at least the important parts her).  Please take note of 3 things

  1. Our controller inherits off of AsyncController which is required to do async controller actions in MVC
  2. My return type is a Task<PartialView> for the action, this is required
  3. In the .ContinueWith I am returning the correct PartialView w/ the data

One thing I want to point out here is that when trying to get the .FromAsync logic to work I keep getting compiler warnings telling me about a mismatch.  This was because at first I was NOT declaring my two Func<T> and just assumed the compiler knew what I meant (guess not).  As soon as I actually defined my 2 Func<T> signatures (I have removed the first one as R# told me it was not needed and sure enough it was not) the compiler was happy.

As you can see, once you make the compiler happy (pesky compiler) this is pretty straight forward.  Hope this helps someone.

Till next time,

Posted 05-13-2012 3:07 PM by Derik Whittaker
Filed under: ,



Pedro Ferreira wrote re: Using TPL to access Async WCF Endpoints in MVC
on 05-13-2012 5:46 PM

I have to say that I haven't played with MVC4 and it's async support, but I think you are doing one extra step that is not required.

I think you should return your Task directly from GetScheduleActivitiesAsync and use that task to add your Continuation.

The final result should be the same, but you don't need to block on GetScheduleActivitiesAsync just to create another task in Listings to wait for that block.

Also, you shouldn't need to create those Func<T> in your FromAsync. Try specifying the type directly in the Task class as: Task<YourResultType>.Factory.FromAsync(channel.Begin..., channel.End..., ...)

John wrote re: Using TPL to access Async WCF Endpoints in MVC
on 05-14-2012 7:46 AM

I was writing the exact same comment as Pedro last night, but your Captcha is impossible to use on an iPad. Can you pass that along to the guys?

About The CodeBetter.Com Blog Network
CodeBetter.Com FAQ

Our Mission

Advertisers should contact Brendan

Google Reader or Homepage Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl Latest Items
Subscribe in Rojo

Member Projects
DimeCasts.Net - Derik Whittaker

Friends of
Red-Gate Tools For SQL and .NET


SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
NHibernate Profiler
Balsamiq Mockups
JetBrains - ReSharper
Web Sequence Diagrams
Ducksboard<-- NEW Friend!


Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers


Community Server (Commercial Edition)