【发布时间】:2015-05-03 22:40:59
【问题描述】:
我需要一个 WCF 服务操作,它接受一个大的流,处理它并返回那个流。
我使用an MSDN article on Large Data Streaming 作为我需要的参考。我听从了那篇文章中的建议。
提前问问题:
我想知道为什么生成的服务操作在合同中指定的时候没有返回类型?
如果这是预期行为,我应该如何让它传递一个流并返回一个已处理的流?
详情:
因为我需要用元数据伴随输入和返回流,所以我根据需要用 MessageContract 属性修饰了类。
以下是我的实现的简要介绍:
消息合同:
[MessageContract]
public class InputStreamMessage
{
[MessageHeader]
public InputStreamHeader Header { get; set; }
[MessageBodyMember(Order = 1)]
public Stream Data { get; set; }
}
[MessageContract]
public class OutputStreamMessage
{
[MessageHeader]
public OutputStreamHeader Header { get; set; }
[MessageBodyMember(Order = 1)]
public Stream Data { get; set; }
}
服务合同:
[ServiceContract]
public interface IStreamService
{
[OperationContract]
OutputStreamMessage ProcessStream(InputStreamMessage input);
}
服务实施:
public OutputStreamMessage DoStreamOperation(InputStreamMessage input)
{
//Some logic that assigns re
OutputStreamMessage output = DoSomeNonBufferedProcessing(input);
return output;
}
客户端:
在客户端,然后生成服务引用,并调用服务如下:
private void PerformStreamOperation()
{
try
{
//
StreamServiceReference.StreamServiceClient client = new StreamServiceReference.StreamServiceReferenceClient();
client.Open();
//Set Header and Parameters
InputMessageHeader header = new InputMessageHeader();
//...
//... initialize header data here
//...
//... do some operation to get input stream
var inputstream = SomeOperationToGetInputStream();
//Perform Service stream action
// ____ [ Why does the generated method have the following signature, retuning void?]
// | [ If this is expected, how do I use it? ]
// |
// V
client.DoStreamOperation(header, ref inputstream);
//...
//... Do what you wish with data
//...
}
catch (Exception ex)
{
MessageBox.Show(ex.Message.ToString(), "Stream Processing Error");
}
}
MSDN 文章使用与official WCF samples. 中存在的完全相同的合同
Stream EchoStream(流数据)
但没有等效 MessageContract 实现的示例。示例版本实现了预期回报。
更新
- 我注意到服务引用具有使用预期方法签名生成的任务/异步方法。也许这意味着当使用带有 Stream 属性的 MessageContract 时,返回一个类似结构的对象,那么您将不得不异步调用它。我没有在任何地方看到它记录在案。将尝试使用这些方法 - 没有按照我们想要的同步操作工作。
-
我也尝试过使用
ChannelFactory作为生成代理客户端的替代方案:EndpointAddress endpoint = new EndpointAddress("net.tcp://localhost:9910/StreamService"); channelFactory = new ChannelFactory<IStreamService>("netTcpStreamedEndPoint"); channelFactory.Endpoint.Contract.SessionMode = SessionMode.Allowed; IStreamService service = channelFactory.CreateChannel();
【问题讨论】:
-
您是否尝试过使用
ChannelFactory而不是添加服务引用,这可能有助于显示问题所在。 -
是的,我用过ChannelFactory。将进行更新
-
好的,使用
ChannelFactory的结果是什么,您是否尝试过打开跟踪并查看是否弹出任何错误? -
将用我尝试过的内容更新问题
标签: c# .net wcf stream messagecontract