Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# WCF服务,由于“错误”引发流异常;意外的文件结尾“;对于传入流_C#_Wcf_Stream - Fatal编程技术网

C# WCF服务,由于“错误”引发流异常;意外的文件结尾“;对于传入流

C# WCF服务,由于“错误”引发流异常;意外的文件结尾“;对于传入流,c#,wcf,stream,C#,Wcf,Stream,我编写了一个exchange传输代理,它将电子邮件正文上载到WCF服务。该服务与Exchange位于同一个框中,侦听localhost:1530以接收传入的TCP连接。传输代理使用.NET3.5框架实现,该服务在.NET4.0框架上实现的Windows服务中自托管 我的问题:为什么在读取完成之前终止流,以及如何修复它? 服务合同的定义如下: [ServiceContract] public interface IReceiveService { [OperationContract]

我编写了一个exchange传输代理,它将电子邮件正文上载到WCF服务。该服务与Exchange位于同一个框中,侦听localhost:1530以接收传入的TCP连接。传输代理使用.NET3.5框架实现,该服务在.NET4.0框架上实现的Windows服务中自托管

我的问题:为什么在读取完成之前终止流,以及如何修复它?

服务合同的定义如下:

[ServiceContract]
public interface IReceiveService
{
    [OperationContract]
    Guid ImportMessage(DateTime dateTimeReceived, string from, IList<string> to, string subject, int attachmentCount, bool bodyEmpty, Guid clientID);

    [OperationContract]
    void ImportMessageBody(IMessageBody body);

    [OperationContract]
    void ImportMessageAttachment(IMessageAttachment attachment);
}
public void ImportMessageBody(IMessageBody body)
{
    Task.Factory.StartNew(() =>
        {
            string fileName = GetFileNameFromMagicalPlace();
            using (FileStream fs = new FileStream(fileName, FileMode.Append))
            {
                body.Data.CopyTo(fs); // <---- throws System.IOException right here
            }
        });
}
[MessageContract]
public class IMessageBody
{
    [MessageHeader]
    public Guid MessageID { get; set; }

    [MessageHeader]
    public string Format { get; set; }

    [MessageBodyMember]
    public System.IO.Stream Data { get; set; }
}
string queueUri = String.Format("net.tcp://localhost:{0}/{1}", port, serviceName);
            try
            {
                host = new ServiceHost(typeof(ReceiveService), new Uri(queueUri));
                host.AddDefaultEndpoints();
                var endpoint = host.Description.Endpoints.First();
                ((NetTcpBinding)endpoint.Binding).TransferMode = TransferMode.Streamed;                 

                trace.Log(Level.Debug,String.Format("Created service host: {0}", host));                

                host.Open();                
                trace.Log(Level.Debug,"Opened service host.");
            }
            catch (Exception e)
            {
                string message = String.Format("Threw exception while attempting to create ServiceHost for {0}:{1}\n{2}", queueUri, e.Message, e.StackTrace);
                trace.Log(Level.Debug,message);
                trace.Log(Level.Error, message);
            }
异常错误为:“错误:读取流时引发异常。”堆栈跟踪:

   at System.ServiceModel.Dispatcher.StreamFormatter.MessageBodyStream.Read(Byte[] buffer, Int32 offset, Int32 count) 
   at System.IO.Stream.CopyTo...
有一个内部异常:

System.Xml.XmlException: Unexpected end of file. Following elements are not closed: Address, IMessageBody, Body, Envelope. 
    at System.Xml.XmlExceptionHelper.ThrowXmlException(XmlDictionaryReader reader, String res, String arg1, String arg2, String arg3) 
    at System.Xml.XmlBufferReader.GetByteHard() 
    at System.Xml.XmlBufferReader.ReadMultiByteUInt31() 
    at System.Xml.XmlBinaryReader.ReadName(StringHandle handle) 
    at System.Xml.XmlBinaryReader.ReadNode() 
    at System.ServiceModel.Dispatcher.StreamFormatter.MessageBodyStream.Read(Byte[] buffer, Int32 offset, Int32 count) 
其他细节如下


IMessageBody
的定义如下:

[ServiceContract]
public interface IReceiveService
{
    [OperationContract]
    Guid ImportMessage(DateTime dateTimeReceived, string from, IList<string> to, string subject, int attachmentCount, bool bodyEmpty, Guid clientID);

    [OperationContract]
    void ImportMessageBody(IMessageBody body);

    [OperationContract]
    void ImportMessageAttachment(IMessageAttachment attachment);
}
public void ImportMessageBody(IMessageBody body)
{
    Task.Factory.StartNew(() =>
        {
            string fileName = GetFileNameFromMagicalPlace();
            using (FileStream fs = new FileStream(fileName, FileMode.Append))
            {
                body.Data.CopyTo(fs); // <---- throws System.IOException right here
            }
        });
}
[MessageContract]
public class IMessageBody
{
    [MessageHeader]
    public Guid MessageID { get; set; }

    [MessageHeader]
    public string Format { get; set; }

    [MessageBodyMember]
    public System.IO.Stream Data { get; set; }
}
string queueUri = String.Format("net.tcp://localhost:{0}/{1}", port, serviceName);
            try
            {
                host = new ServiceHost(typeof(ReceiveService), new Uri(queueUri));
                host.AddDefaultEndpoints();
                var endpoint = host.Description.Endpoints.First();
                ((NetTcpBinding)endpoint.Binding).TransferMode = TransferMode.Streamed;                 

                trace.Log(Level.Debug,String.Format("Created service host: {0}", host));                

                host.Open();                
                trace.Log(Level.Debug,"Opened service host.");
            }
            catch (Exception e)
            {
                string message = String.Format("Threw exception while attempting to create ServiceHost for {0}:{1}\n{2}", queueUri, e.Message, e.StackTrace);
                trace.Log(Level.Debug,message);
                trace.Log(Level.Error, message);
            }
显示相关位的传输代理的缩写版本(我希望):


嗯,代码太多了。您应该尽量将代码最小化到尽可能小的可复制示例。我想问题可能在这里:

public void ImportMessageBody(IMessageBody body)
{
    Task.Factory.StartNew(() =>
        {
            string fileName = GetFileNameFromMagicalPlace();
            using (FileStream fs = new FileStream(fileName, FileMode.Append))
            {
                body.Data.CopyTo(fs); // <---- throws System.IOException right here
            }
        });
}
public void导入消息体(IMessageBody)
{
Task.Factory.StartNew(()=>
{
字符串文件名=GetFileNameFromMagicalPlace();
使用(FileStream fs=newfilestream(fileName,FileMode.Append))
{

body.Data.CopyTo(fs);//问题本质上是我通过调用
Task.Factory.StartNew
来执行不必要的并发操作,而不是通过
servicebeaviorAttribute
来确保我的服务正确配置为并发。感谢Ladislav为我指明了正确的方向。

Ladislav,谢谢你的回答(还有你另一个答案的链接!)我发布了这么多代码,因为我不知道问题出在哪里,这是我所关心的最小可能的可复制示例。这毕竟不是问题所在。我现在已将我的
ImportMessageBody
操作与
[OperationBehavior]降级(AutoDisposeparameters=false)
并实现了一个
操作已完成
事件处理程序,但
Stream.CopyTo
仍然以与以前相同的方式失败。不过,看起来您走对了方向,因为当我在
ImportMessageBody
实现中同步执行
Stream.CopyTo
时(也就是说,没有
任务
),它可以工作……这很有意义,因为不需要像这样手动实现并发。WCF为您实现并发。我将此标记为答案,因为它为我指明了正确的方向,即使它最终不是答案。