c# - 如何构建批量返回数据的WCF服务

标签 c# .net wcf

我正在尝试构建一个 WCF 服务,该服务接收请求记录并返回这些记录的字符串响应。我正在接受一系列请求记录。在这个数组中,一些记录被快速处理(“快速记录”),而其他记录则需要时间(“慢速记录”)。那么,与其等待所有记录被处理,不如先返回快速记录,然后再发送慢速记录?客户端会立即更新屏幕中的快记录,并在慢记录通过时更新。

如何使用 WCF 服务执行此操作?

最佳答案

如果您可以提供双工支持,我会通过回调来实现。

[ServiceContract]
public interface IMyServiceCallback
{        
    [OperationContract(IsOneWay = true)]        
    void OnRecordResult(string result);
}

[ServiceContract(CallbackContract = typeof(IMyServiceCallback))]
public interface IMyService
{
    [OperationContract(IsOneWay = true)]
    void GetRecords(string parameter);
}

public class MyService: IMyService
{
    public void GetRecords(string parameter)
    {
        var callback = OperationContext.Current.GetCallbackChannel<IMyServiceCallback>();

        using(var resultCollection = ProcessRecords(parameter))
        {
            foreach(var record in resultCollection.GetConsumingEnumerable())
            {
                //Transmit the results back to the client as they get put in to resultCollection.
                callback.OnRecordResult(record);
            }
        }

        //We return null as a signal that we are done reporting results, you could also add a 2nd method to the callback to represent being done.
        callback.RecordResult(null);
    }

    private static BlockingCollection<string> ProcessRecords(string parameter)
    {
         var collection = new BlockingCollection<string>();

         //We populate the blocking collection in a background thread.
         Task.Run(() => StartProcessingRecords(parameter, collection);

         return collection;
    }

    private static void StartProcessingRecords(string parameter, BlockingCollection<string> collection)
    {
        //...
    }
}

这是你如何在客户端中使用它

public class MyServiceClient : DuplexClientBase<IMyService>
{
    public MyServiceClient(object callbackInstance, Binding binding, EndpointAddress remoteAddress)
        : base(callbackInstance, binding, remoteAddress) { }
}

public class MyServiceCallbackClient : IMyServiceCallback
{
    public event EventHandler<string> RecordResult; //If you are not using .net 4.5 you will need a custom class.

    void IMyServiceCallback.OnRecordResult(string result)
    {
       var tmp = RecordResult;
       if(tmp != null)
           tmp(this, result);
    }
}

IEnumerable<string> GetRecords(string parameter)
{
    var uri = //...
    var binding = //...

    using(var collection = new BlockingCollection<string>())
    {
        var callback = new MyCallbackClient();
        callback.RecordResult += (o, result) =>
        {
             if(result != null)
                 collection.Add(result);
             else
                 collection.CompleteAdding(); //when we get a null we mark the collection complete
        }


        var client = new MyServiceClient(callback, binding, new EndpointAddress(uri));
        var proxy = client.ChannelFactory.CreateChannel();
        proxy.GetRecords();

        foreach(var record in collection.GetConsumingEnumerable())
        {
            yield return record;
        }

        client.Close();
     }
}

关于c# - 如何构建批量返回数据的WCF服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19458628/

相关文章:

.net - LESS 与文化代码结合使用

C# 生成的代理方法与原始 Java 服务方法不同

c# - 以编程方式启用动态压缩的最佳方法是什么?

c# - 使用 Win32 库时,您更喜欢使用哪个 PE 查看器应用程序?

C# 字典 - 字典中不存在给定的键

c# - XAudio2 与 C#

c# - 按“后退浏览器”按钮将丢失上一页状态

c# - 如何为类中的值类型变量分配内存

xml - 在 WCF 中修改 XML 响应;损坏的 XML

c# - 如何进行多线程安全的原子对象创建和交换