I have a WCF REST service consumed in an ASP.Net site, from a page, using AJAX.
I want to be able to call methods from my service async, which means I will have callback handlers in my javascript code and when the methods finish, the output will be updated. The methods should run in different threads, because each method will take different time to complete their task
I have the code semi-working, but something strange is happening because the first time I execute the code after compiling, it works, running each call in a different threads but subsequent calls blocs the service, in such a way that each method call has to wait until the last call ends in order to execute the next one. And they are running on the same thread. I have had the same problem before when I was using Page Methods, and I solved it by disabling the session in the page but I have not figured it out how to do the same when consuming WCF REST services
Note: Methods complete time (running them async should take only 7 sec and the result should be: Execute1 - Execute3 - Execute2)
Execute1 -- 2 sec
Execute2 -- 7 sec
Execute3 -- 4 sec
Output After compiling
Output subsequent calls (this is the problem)
I will post the code...I'll try to simplify it as much as I can
Service Contract
[ServiceContract(
SessionMode = SessionMode.NotAllowed
)]
public interface IMyService
{
// I have other 3 methods like these: Execute2 and Execute3
[OperationContract]
[WebInvoke(
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json,
UriTemplate = "/Execute1",
Method = "POST")]
string Execute1(string param);
}
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(
InstanceContextMode = InstanceContextMode.PerCall
)]
public class MyService : IMyService
{
// I have other 3 methods like these: Execute2 (7 sec) and Execute3(4 sec)
public string Execute1(string param)
{
var t = Observable.Start(() => Thread.Sleep(2000), Scheduler.NewThread);
t.First();
return string.Format("Execute1 on: {0} count: {1} at: {2} thread: {3}", param, "0", DateTime.Now.ToString(), Thread.CurrentThread.ManagedThreadId.ToString());
}
}
ASPX page
<%@ Page EnableSessionState="False" Title="Home Page" Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true"
CodeBehind="Default.aspx.cs" Inherits="RestService._Default" %>
<asp:Content ID="HeaderContent" runat="server" ContentPlaceHolderID="HeadContent">
<script type="text/javascript">
function callMethodAsync(url, data) {
$("#message").append("<br/>" + new Date());
$.ajax({
cache: false,
type: "POST",
async: true,
url: url,
data: '"de"',
contentType: "application/json",
dataType: "json",
success: function (msg) {
$("#message").append("<br/> " + msg);
},
error: function (xhr) {
alert(xhr.responseText);
}
});
}
$(function () {
$("#callMany").click(function () {
$("#message").html("");
callMethodAsync("/Execute1", "hello");
callMethodAsync("/Execute2", "crazy");
callMethodAsync("/Execute3", "world");
});
});
</script>
</asp:Content>
<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<input type="button" id="callMany" value="Post Many" />
<div id="message">
</div>
</asp:Content>
Web.config (relevant)
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
</system.webServer>
<system.serviceModel>
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" multipleSiteBindingsEnabled="true" />
<standardEndpoints>
<webHttpEndpoint>
<standardEndpoint name="" helpEnabled="true" automaticFormatSelectionEnabled="true" />
</webHttpEndpoint>
</standardEndpoints>
</system.serviceModel>
Global.asax
void Application_Start(object sender, EventArgs e)
{
RouteTable.Routes.Ignore("{resource}.axd/{*pathInfo}");
RouteTable.Routes.Add(new ServiceRoute("",
new WebServiceHostFactory(),
typeof(MyService)));
}