6

我现在有这样的东西:

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 
    }

 ...
}

是否可以制作有状态的 Web 服务,以便我可以重用SomeObj so并调用同一个对象上的方法?

因此,将使用此服务的客户端将首先调用 Web 方法,该方法将创建so对象并返回一些 ID。然后在随后的调用中,Web 服务将so根据 ID 重用相同的对象。

编辑


这是我的实际代码:

[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);               
}
4

3 回答 3

6

有状态的 Web 服务不可扩展,我不推荐它们。相反,您可以将昂贵操作的结果存储在缓存中。该缓存可以通过自定义提供程序分发以获得更好的可扩展性:

[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;
}
于 2010-11-07T12:59:32.763 回答
1

选项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 开始请求方法并在执行完成时获得回调。您可能需要调整 Web 服务客户端类的超时参数才能使其正常工作。

选项 3

您可以使用SixPack 库缓存功能轻松做到这一点!;-)


[评论后编辑] 现在选项 1 中有两个静态字段,以允许两个不同的实例,每个方法一个,根据要求。


[进一步解释后编辑] 使用 Session 使调用有状态。

请参阅:http: //msdn.microsoft.com/en-us/library/aa480509.aspx

还添加了选项 3。

于 2010-11-07T13:56:11.957 回答
0

ServiceContract将您的界面更改为:

[ServiceContract(SessionMode = SessionMode.Required)]

并将以下属性放在您的类上:

[ServiceBehaviorAttribute(InstanceContextMode = InstanceContextMode.PerSession)]

有关更多信息和示例,请参阅http://msdn.microsoft.com/en-us/library/system.servicemodel.sessionmode.aspx 。

于 2010-11-07T13:46:01.747 回答