Se agotó el tiempo de espera de las llamadas WCF si creó el host del servicio WCF dentro del controlador ASP.NET MVC

Este artículo ayuda a resolver el problema de Windows Communication Foundation (WCF) en el que se agotó el tiempo de espera de las llamadas si se crea el host del servicio WCF dentro del controlador del controlador de vista de modelo de ASP.NET (MVC).

Versión del producto original:   Windows Communication Foundation 4,0, Microsoft .NET Framework 4,0
Número de KB original:   2621732

Síntomas

Se agotó el tiempo de espera de la llamada de WCF si el host de servicio se creó en ASP.NET controlador de MVC.

Causa

Este es un escenario de interbloqueo, que la llamada de cliente de WCF se origina en ASP.NET controlador de MVC. Además, el host del servicio WCF se creó también en el controlador de MVC de ASP.NET.

Este es un código de ejemplo que puede reproducir este problema. Supongamos que la aplicación se ha hospedado en https://localhost/wcfselfhostinmvc . A continuación, las solicitudes siempre que se https://mywebsite/wcfselfhostinmvc/home/index agote el tiempo de espera.

public class HomeController : Controller  
{  
    private static ServiceHost SvcHost = null;  
    public ActionResult Index()  
    {  
        //Create the service host  
        if (null == SvcHost)  
        {  
        SvcHost = new ServiceHost(typeof(HelloWorld));  
        SvcHost.Open();  
    }  

    //Create the Client  
    EndpointAddress address = new EndpointAddress("net.pipe://localhost/WCFSelfHostInMVC/HelloWorld");  
    NetNamedPipeBinding binding = new NetNamedPipeBinding();  
    binding.Security.Mode = NetNamedPipeSecurityMode.None;  
    ChannelFactory<IHelloWorld> factory = new  
    ChannelFactory<IHelloWorld>(binding, address);  
    IHelloWorld channel = factory.CreateChannel();  
    //This call always timed out  
    ViewBag.Message = channel.DoWork();  
    return View();  
}  

Esto se debe a un interbloqueo relacionado con el AspNetSynchronizationContext objeto. El subproceso de cliente de WCF (subproceso de MVC) mantenía el bloqueo de AspNetSynchronizationContext como es una solicitud de ASP.net y estaba esperando la respuesta de la llamada al servicio WCF. Sin embargo, el subproceso del servicio WCF requiere bloqueo para que el pueda AspNetSynchronizationContext procesar la solicitud de WCF.

Los motivos por los que WCF usa AspNetSynchronizationContext son:

  1. ServiceBehaviorAttribute UseSynchronizationContextSe establece en true (de forma predeterminada).
  2. El host del servicio WCF se crea en el contexto de ASP.NET (como se ha creado en el código de demostración, se ha creado dentro del controlador MCV).

Solución

Hay varias soluciones disponibles:

  • Valor ServiceBehaviorAttribute UseSynchronizationContext en false.

  • Crear el host de servicio en el Application_Start.

  • Según. Archivo SVC para crear o activar el host de servicio.

Más información