ADO.NET Data Services, Entity Framework und SQL/HTTP Timeouts

timeouts Beim Arbeiten mit den ADO.NET Data Services (aka Astoria) kommt man irgendwann an den Punkt, dass die Aufgaben komplizierter werden oder die Last auf die Server steigt. In solchen Situationen ist man mit potentiellen Timeouts in allen Ebenen konfrontiert. In diesem Post zeige ich welche Timeouts es gibt, aber speziell will ich zeigen wie ich das Timeout des Entity Frameworks (SQL) in Kombination mit der MS REST Schicht ADO.NET Data Services anpassen kann.

Es bleibt anzumerken, dass in der aktuellen Version V1 ein Bug existiert. Die Serverkomponente wirft bei einem Timeout eine NullReferenceException anstatt die eigentliche Fehlermeldung, was leider nicht wirklich weiter hilft.

Welche Timeouts gibt es also und was sind die Defaults:

  1. HTTP Client Timeout – Browser
    Leider habe ich hier kaum Informationen gefunden… nichts was ich hier schreiben möchte.
  2. HTTP Client Timeout – ADO.NET Data Services Client Library
    Wo: Code
    Default: 100.000 Millisekunden (100 Sekunden) vererbt von HttpWebRequest.Timeout
    Mehr: MSDN – System.Data.Services.Client.DataServiceContext.Timeout
    Mehr: Microsoft KB 962933: Client Timeout Bug
    Mehr: ADO.NET Data Services Team Blog: Client Timeout Bug
  3. HTTP Server ExecutionTimeout
    Wo: web.config
    Default: 110 Sekunden (wenn Debug=False, dann unendlich)
    Mehr: httpRuntime Element (ASP.NET Settings Schema)
  4. ADO.NET Data Services Server Library
    Hier gibt es kein extra Timeout. Die unterliegende Connection (zum Beispiel SQL) bestimmt die Dauer.
  5. Entity Framework Connection/Command Timeout (SQL)
    Wo: Code
    Default: 30 Sekunden CommandTimeout
    Default: 15 Sekunden SqlConnection

Wenn wir uns nun um ein Timeout kümmern müssen wir also immer checken, ob wir damit gegen ein anderes rennen. Angenommen wir wollen unseren Sql Queries 5 Minuten Zeit geben (nur für das Beispiel!), dann müssen wir folgendes tun:

  1. Entity Framework Timeout = 5*60 = 300 Sekunden
  2. HttpServer Timeout = 5*60 + 10 (Puffer) = 310 Sekunden
  3. ADO.NET Data Services Client Timeout = 5*60*1000 + 20*1000 (Puffer) = 320.000 Millisekunden (320 Sekunden)

Wichtig: Wir brauchen überall ein wenig Puffer, sonst kann es sein, dass uns die Gesamtgeschwindigkeit der Maschine (da kann ja noch mehr Code dazwischen laufen) dazwischenkommt.

Jetzt zum eigentlichen Inhalt des Posts ;-) Wie kann ich überhaupt das Timeout des Entity Frameworks erhöhen. Die ADO.NET Data Service Website nutzt das Entity Framework und stellt so die Tabellen und Views zur Verfügung. Der Default Code in den SVC Dateien erlaubt es nicht die Connection zu beeinflussen:

 using System;
using System.Web;
using System.Collections.Generic;
using System.ServiceModel.Web;
using System.Linq;
using System.Data.Services;
using NorthwindModel;
namespace SimpleDataService
{
public class Northwind : DataService<NorthwindEntities>
{
public static void InitializeService(IDataServiceConfiguration config)
{
config.SetEntitySetAccessRule("*", EntitySetRights.All);
}
}
}

Die Klasse DataService<T> bietet nun eine Methode CreateDataSource mit der ich von Hand die EntityConnection erzeugen kann und somit auch den Command Timeout setzen kann:

protected override NorthwindEntities CreateDataSource()
{
var dbcon = new NorthwindEntities();
dbcon.CommandTimeout = Core.Config.Application.TimeoutSql; //Core is my helper library
return dbcon;
}

Ich hoffe ich kann dem einen oder anderen weiter helfen :-) Mir weiter geholfen bei der Lösung hat folgender Blogpost:

Timeout in ADO.Net Entity Framework and ADO.Net Data Services

Ciao Marco

Comments are currently closed.