1

Inspired by How to: Implement an Asynchronous Service Operation and Building Task Based WCF Services with Task Parallel Library, I'm trying to make a WCF web service with an operation that is executed asynchronously.

The idea is that I have a method that does work that lasts anywhere from a second to a minute that is called by a button on a web page and I have a timer that calls another method in the same service that eventually will return the asynchronous operation's status (working or not).

So I set up a dummy example and my asynchronous operation actually blocks my Web Serivce.

[ServiceContract(Namespace = "")]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall, ConcurrencyMode = ConcurrencyMode.Multiple)]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
public class Service1
{
    [OperationContract(AsyncPattern = true, Action = "TestServiceMethod", Name = "TestServiceMethod", ReplyAction = "TestServiceMethodReply")]
    public IAsyncResult BeginTestServiceMethod(string request, AsyncCallback callback, object asyncState)
    {
        var task = new Task<string>((state) =>
        {
            SpinWait.SpinUntil(() => { return false; }, 5000);
            return request;
        }, asyncState);

        task.ContinueWith((t) => { callback(t); });
        task.Start();

        return task;
    }

    public string EndTestServiceMethod(IAsyncResult result)
    {
        var task = (Task<string>)result;
        return task.Result;
    }

    [OperationContract]
    public string OtherTest()
    {
        return "OtherTest";
    }
}

and this is the javascript on my page (the click function is activated by clicking a button)

function Click() {
    var service = new Service1();
    service.TestServiceMethod("Dummy", PopWord);
    service.OtherTest(PopWord);
}

function PopWord(word) {
    alert(word);
}

The result is a 5 seconds wait when I click on the button, followed by "Dummy" and "OtherTest" popping one after the other. Expected behavior would be "OtherTest" popping with "Dummy" 5 seconds later.

Can anyone spot what I am doing wrong or perhaps suggest another approach?

dee-see
  • 23,668
  • 5
  • 58
  • 91

1 Answers1

2

I'm guessing you are running on cassini (development server) and not on IIS?

If so, I've seen quite a few people saying that cassini cannot execute requests in parallel.

I can't seem to locate any documentation on this from microsoft but there are quite a few posts on stack overflow similar to the following.

ASP.NET Development Server concurrent processing doesn't work

ASP.NET Dev Server (Cassini), IIS Express and multiple threads

Community
  • 1
  • 1
Kenneth Ito
  • 5,201
  • 2
  • 25
  • 44
  • Indeed I am. I'll try running it on IIS tonight and I'll tell you how it went. Thanks. – dee-see May 10 '12 at 10:58
  • Any luck? Would be great to get something definitive. – Kenneth Ito Jun 07 '12 at 07:35
  • Excuse me for taking so long. I've had problems that required reinstalling Windows and it took a while for me to do it. So indeed it seems like the Dev Server was a part of the problem, but I have a different one now. Clicking on my button (or on a text link with an onClick event) still doesn't work, but I do have the expected asynchronous behavior if I type `javascript:Click()` in my address bar. Do you have any clue of why this would happen? – dee-see Jul 10 '12 at 00:40
  • Good to know that cassini really is the issue, wish I could find some more authoritative documentation saying that it doesn't handle concurrency. As to the Click problem, can you post the way you are wiring up your click? – Kenneth Ito Jul 10 '12 at 01:01
  • I played with it some more and actually it seems pretty random. Sometimes it works, sometimes it doesn't (button, link or url bar). I'm using an `` with `OnClientClick="Click();"`. – dee-see Jul 10 '12 at 01:09
  • Unless you want a postback, you probably want to go with OnClientClick="Click(); return false;" It's possible it was only working some of the time because the postback occurred before the client click. – Kenneth Ito Jul 10 '12 at 01:11
  • Yeah indeed, but this is just a dummy and I didn't care. I wasn't sure if it really worked occasionally or if the order of the calls was just switched around while still being synchronous. So I changed my test to two calls of the async function that waits 5 seconds. Result: 5 seconds, popup, 5 seconds, popup. So indeed it was only the order of the calls being switched around and IIS didn't fix anything afterall. :S – dee-see Jul 10 '12 at 01:13
  • Hmm, another thing you can try is disabling or readonly'ing your session state. I know in MVC there's a lock around session that serializes requests if session is writable (to prevent concurrent requests from corrupting in proc session). Possible vanilla asp.net has something similar. – Kenneth Ito Jul 10 '12 at 01:19
  • Yah there is a session lock. "If two concurrent requests are made for the same session (by using the same SessionID value), the first request gets exclusive access to the session information. The second request executes only after the first request is finished. (The second session can also get access if the exclusive lock on the information is freed because the first request exceeds the lock time-out.) http://msdn.microsoft.com/en-us/library/ms178581.aspx – Kenneth Ito Jul 10 '12 at 01:20
  • Thank you very much! Setting the session state as read only in the `@ Page` didn't change anything for some reason, but changing it in `Application_BeginRequest` did the job just fine (inspired by http://blogs.microsoft.co.il/blogs/idof/archive/2010/09/27/asp-net-compatible-wcf-services-concurrency-problem.aspx ) – dee-see Jul 12 '12 at 03:05
  • Glad to help! Especially someone with a question to answer ratio like yours ;) – Kenneth Ito Jul 12 '12 at 03:38