2013-02-06 106 views
0

起初我有一个LINQ查询(说EF或任何其他)预计递延执行:是否可以通过WCF实现/保留延迟执行?

class Provider : IProvider 
{ 
    public IEnumerable<Any> GetSome() 
    { 
     yield return new Any(); // LINQ query 
    } 
} 

但现在这样一个提供移动到一个WCF服务(和IOC):

unityContainer.RegisterType<IProvider>(
    new PerResolveLifetimeManager(), 
    new InjectionFactory(c => new ChannelFactory<T>("IService").CreateChannel())); 

是有可能通过WCF调用保留延迟执行?

+0

你预计会发生什么?客户是否要求每件物品?因为这是通过电线推迟执行所需要的。 –

+0

@DanielHilgarth:是的,我想知道是否有可能在实现时要求每个项目轮流轮流。下面是一个例子:我有一些重要的EF调用,WCF客户端必须等待它完成,而不是序列化整个结果集,反序列化它,并且只能开始迭代。而不是开始处理之前的第一个结果将从数据库读取/从服务接收。 – abatishchev

+0

这是关于流媒体 - 而不是延期执行...即使使用WCF流媒体,它可能无法正常工作。您将不得不进行非常低级别的HTTP(分块编码)或TCP编程来实现这一点。 –

回答

1

这个答案实际上是您对Ladislav Mrnka最后评论的答案。你说:

好吧,我明白了,所以没有“免费的甜甜圈”可能。在LINQ to Any中,我们有这样的行为,但有必要跨越服务边界,即数据被(序列化),打破它,对吧?

虽然它不是免费的,但它仍然是可能的!

在服务器端,你必须提供一个初始化请求的方法和一个方法来逐个获取结果。

在客户端 - 特别是在其低级别的基础设施类中 - 您可以将其包装在枚举器中,最后,您的“业务”类可以像使用其他枚举器一样使用该枚举器。

我们已经讨论过,它会在每个项目所需的请求 - 响应方式中引入额外开销。这会引入延迟并增加网络负载。

使用伪的RESTful API可能看起来像这样这种方法的一个样本:

服务器端:

  • POST http://server/api/search-specification
    主体包含需要为您的搜索,例如参数开始日期和结束日期
    响应将是标识搜索规范的URI。
  • GET http://server/api/search-specification/1/next-result
    回应将是下一个项目。

这个控制器看起来是这样的:

public Response PostSearchSpecification(SearchSpecification spec) 
{ 
    int id = _searches.Max(x => x.Key) + 1; // Make thread-safe 
    _searches[id] = _provider.GetSome().GetEnumerator(); 
    return ...; 
} 

public Item GetNextResult(int searchSpecId) 
{ 
    if(_searches[searchSpecId].MoveNext()) 
     return _searches.Current; 
    else 
     return null; // or return a HTTP status code that tells the 
        // client that there are no more items. 
} 

我称它是假的RESTful API,因为它肯定看起来像一个,但它需要在内部保持状态,每种规格启用延期执行。另外GET http://server/api/search-specification/1/next-result不是幂等的。
但我认为这证明了我的意思:)

的客户端会以某种方式封装它是这样的:

class Search 
{ 
    public IEnumerable<Item> Start(params) 
    { 
     var client = new HttpClient(...); 
     var resultsUri = client.Post(new SearchSpecification(params)).Response; 
     Item item = client.Get<Item>(resultsUri); 
     while(item != null) 
     { 
      yield return item; 
      item = client.Get<Item>(resultsUri); 
     } 
    } 
} 

而且你会使用这样的:

var search = new Search(); 

foreach(var item in search.Start(...)) 
    // ... 

只是一个关于如何实现这样的东西的原始素描。

相关问题