Вопрос

Теперь у меня есть что -то вроде этого:

public class Service1 : System.Web.Services.WebService
{
    [WebMethod]
    public string Method1()
    {
        SomeObj so = SomeClass.GetSomeObj(); //this executes very long time, 50s and more
        return so.Method1(); //this exetus in a moment 
    }

    [WebMethod]
    public string Method2()
    {
        SomeObj so = SomeClass.GetSomeObj(); //this executes very long time, 50s and more
        return so.Method2(); //this exetus in a moment 
    }

 ...
}

Можно ли создавать веб -сервис Stateful, чтобы я мог повторно использовать SomeObj so И просто вызовите методы на том же объекте?

Таким образом, клиент, который будет использовать эту службу, сначала вызовет веб -метод, который будет создавать so объект и верните немного удостоверения личности. А затем в последующих вызовах веб -сервис будет повторно использовать то же самое so объект на основе идентификатора.

РЕДАКТИРОВАТЬ


Вот мой фактический код:

[WebMethod]
public List<ProcInfo> GetProcessList(string domain, string machineName)
{
    string userName = "...";
    string password = "...";
    TaskManager tm = new TaskManager(userName, password, domain, machineName);

    return tm.GetRunningProcesses();
}

[WebMethod]
public bool KillProcess(string domain, string machineName, string processName)
{
    string userName = "...";
    string password = "...";
    (new TaskManager(userName, password, domain, machineName);).KillProcess(processName);               
}
Это было полезно?

Решение

Служба Stateful Web Services не масштабируемы, и я бы не рекомендовал их. Вместо этого вы можете сохранить результаты дорогих операций в кеш. Отказ Этот кэш может быть распределен через пользовательских провайдеров для лучшей масштабируемости:

[WebMethod]
public string Method1()
{
    SomeObj so = TryGetFromCacheOrStore<SomeObj>(() => SomeClass.GetSomeObj(), "so");
    return so.Method1(); //this exetus in a moment 
}

[WebMethod]
public string Method2()
{
    SomeObj so = TryGetFromCacheOrStore<SomeObj>(() => SomeClass.GetSomeObj(), "so");
    return so.Method2(); //this exetus in a moment 
}

private T TryGetFromCacheOrStore<T>(Func<T> action, string id)
{
    var cache = Context.Cache;
    T result = (T)cache[id];
    if (result == null)
    {
        result = action();
        cache[id] = result;
    }
    return result;
}

Другие советы

Опция 1

Вы можете использовать свой httpsession.

//this executes very long time, 50s and more, but only once.
private SomeObj SessionSomeObj { 
  get 
  { 
    var ret = (SomeObj)Session["SomeObjStore"] ?? SomeClass.GetSomeObj();
    SessionSomeObj = ret;
    return ret; 
  }
  set { Session["SomeObjStore"] = value; }
}

[WebMethod(EnableSession = true)]
public string Method1()
{
    return SessionSomeObj.Method1(); //this exetus in a moment 
}

[WebMethod(EnableSession = true)]
public string Method2()
{
    return SessionSomeObj.Method2(); //this exetus in a moment 
}

Обратите внимание, что это будет работать только в том случае, если один вызов на клиента будет сделан за раз.

Вариант 2

Вы можете оставить класс как есть, но использовать WebMethod по -разному. Если вы звоните из .NET, сгенерированного классом, async Методы предоставляются для этих событий. В основном вы вызовыте метод запроса Method1 и получаете обратный вызов, когда выполнение завершено. Возможно, вам потребуется настроить параметр тайм -аута класса клиента веб -службы, чтобы это было работать.

Вариант 3

Вы можете использовать Кэширование функций из Библиотека Sixpack делать это без усилий! ;-)


Под редакцией после комментария В настоящее время в варианте 1 есть два статических поля, чтобы разрешить два разных экземпляра, по одному методу, по запросу.


Под редакцией после дальнейшего объяснения Использование сеанса, чтобы сделать вызовы государственными.

Видеть: http://msdn.microsoft.com/en-us/library/aa480509.aspx

Также добавлено вариант 3.

Изменить ServiceContract вашего интерфейса в:

[ServiceContract(SessionMode = SessionMode.Required)]

И поместите следующий атрибут в свой класс:

[ServiceBehaviorAttribute(InstanceContextMode = InstanceContextMode.PerSession)]

Видеть http://msdn.microsoft.com/en-us/library/system.servicemodel.sessionmode.aspx Для получения дополнительной информации и примера.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top