C# 在wcf客户端代理中调用方法时偶尔出现异常

C# 在wcf客户端代理中调用方法时偶尔出现异常,c#,.net,wcf,C#,.net,Wcf,有时,在我的xp机器上,在自动生成的客户端代理中调用方法时会出现异常。我告诉调试器停止所有clr异常。 现在,有时当我调用以下命令时: public MyStuff.Entities.Package GetPackageById(System.Guid sessionId, int packageId) { return base.Channel.GetPackageById(sessionId, packageId); } 我首先得到一个InvalidOper

有时,在我的xp机器上,在自动生成的客户端代理中调用方法时会出现异常。我告诉调试器停止所有clr异常。 现在,有时当我调用以下命令时:

public MyStuff.Entities.Package GetPackageById(System.Guid sessionId, int packageId)
    {
        return base.Channel.GetPackageById(sessionId, packageId);
    }
我首先得到一个InvalidOperationException:集合被修改。。。 按F10将导致FileLoadException,并显示以下消息:

无法加载文件或程序集“System.Runtime.Serialization.resources,Version=4.0.0.0,Culture=de,PublicKeyToken=b77a5c561934e089”或其依赖项之一操作在当前状态下不合法。(HRESULT的例外:0x80131509)

我确信服务没有抛出异常,因为它将显示为FaultException。由于调用base.Channel.GetPackageById(sessionId,packageId)时抛出的是一个无效操作异常,我想这不是我的过错吧

我慢慢地失去了可以尝试消除或解决此异常的想法

当使用安装了windows 7和.NET 4.5的开发人员计算机时,这种情况从未发生过。在XP上,这种情况大约会发生4次中的1次

服务端的GetPackageById如下所示:

public Package GetPackageById(Guid sessionId, int packageId)
        {
            try
            {
                return DataProvider.Provider.GetPackagesByKey(packageId,null);
            }
            catch (Exception ex)
            {
                throw new FaultException<MySericeFault>(new MySericeFault(ex));
            }                        
        }
    [DataContract(IsReference = true)]
    [KnownType(typeof(MyApp.Entities.MachinePackage))]
    public partial class Package: INotifyPropertyChanged
    {
    private DateTime? _outDate;
    [DataMember]
    public DateTime? OutDate
    {
        get { return _outDate; }
        set
        {
            if (_outDate != value)
            {
                _outDate = value;
                OnPropertyChanged("OutDate");
            }
        }
    }

    private int _productId;
    [DataMember]
    public int ProductId
    {
        get { return _productId; }
        set
        {
            if (_productId != value)
            {
                _productId = value;
                OnPropertyChanged("ProductId");
            }
        }
    }
    protected virtual void OnPropertyChanged(String propertyName)
    {
        if (_propertyChanged != null)
        {
            _propertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged
    {
        add { _propertyChanged += value; } 
        remove { _propertyChanged -= value; }
    }
    private event PropertyChangedEventHandler _propertyChanged;
    }

这更像是一个实验,但太大了,不能作为评论

尝试创建执行以下代码的新操作合同:

服务:

public Package GetPackageByIdTest(Guid sessionId, int packageId)
{
    return new Package { ProductId = packageId, OutDate = DateTime.Now };
}
static void Main(string[] args)
{
    for (int tester = 0; tester < 2000; tester++)
    {
        using (var service = new ConsoleApplication1.ServiceReference1.Service1Client())
        {
            Package result = service.GetPackageByIdTest(Guid.NewGuid(), tester);
            Console.WriteLine(result.ProductId);
        }
    }

    Console.ReadKey();
    return;
}
然后创建一个引用您的服务的控制台应用程序,并编写如下内容:

public Package GetPackageById(Guid sessionId, int packageId)
        {
            try
            {
                return DataProvider.Provider.GetPackagesByKey(packageId,null);
            }
            catch (Exception ex)
            {
                throw new FaultException<MySericeFault>(new MySericeFault(ex));
            }                        
        }
    [DataContract(IsReference = true)]
    [KnownType(typeof(MyApp.Entities.MachinePackage))]
    public partial class Package: INotifyPropertyChanged
    {
    private DateTime? _outDate;
    [DataMember]
    public DateTime? OutDate
    {
        get { return _outDate; }
        set
        {
            if (_outDate != value)
            {
                _outDate = value;
                OnPropertyChanged("OutDate");
            }
        }
    }

    private int _productId;
    [DataMember]
    public int ProductId
    {
        get { return _productId; }
        set
        {
            if (_productId != value)
            {
                _productId = value;
                OnPropertyChanged("ProductId");
            }
        }
    }
    protected virtual void OnPropertyChanged(String propertyName)
    {
        if (_propertyChanged != null)
        {
            _propertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged
    {
        add { _propertyChanged += value; } 
        remove { _propertyChanged -= value; }
    }
    private event PropertyChangedEventHandler _propertyChanged;
    }
客户端:

public Package GetPackageByIdTest(Guid sessionId, int packageId)
{
    return new Package { ProductId = packageId, OutDate = DateTime.Now };
}
static void Main(string[] args)
{
    for (int tester = 0; tester < 2000; tester++)
    {
        using (var service = new ConsoleApplication1.ServiceReference1.Service1Client())
        {
            Package result = service.GetPackageByIdTest(Guid.NewGuid(), tester);
            Console.WriteLine(result.ProductId);
        }
    }

    Console.ReadKey();
    return;
}
static void Main(字符串[]args)
{
对于(int tester=0;tester<2000;tester++)
{
使用(var service=new ConsoleApplication1.ServiceReference1.Service1Client())
{
包结果=service.GetPackageByIdTest(Guid.NewGuid(),tester);
Console.WriteLine(result.ProductId);
}
}
Console.ReadKey();
返回;
}

然后,试着在一台已知的XP机器上运行它,看看你是否遇到同样的问题。如果没有,则表明您的
DataProvider.Provider.GetPackagesByKey(…)
方法中出现了错误。

听起来好像WCF连接正在异常终止,可能是正在序列化的对象失败。您是否有代码显示对象正在序列化,以便我们可以检查属性等。循环引用通常会导致此类问题。如何关闭与服务的连接?当您得到第一个异常时,该句柄是如何处理的?我想你们需要发布模式代码,得到一个死板的答案!正如在第一句中所写的,它是用svcutil(.NET 4)自动生成的。你能发布
GetPackageById
方法的内容吗?@Jocke:我按照microsoft的建议关闭它:尝试{…client.close}catch{client.abort}我故意关闭并重新打开该服务,以尝试将其绊倒,但我认为它可以正常工作,因为我怀疑真正的问题在于提供商。我今天将尝试。谢谢。我用这个测试了我的服务呼叫,结果证明我的服务非常健壮。我一开始就推迟了客户的一些电话,现在它就像一个符咒。我想在Windows XP真正消失之前,我将不得不像这样离开它!即使它没有真正回答我最初提出的问题,但接受它作为答案是否合理?这真的取决于你。如果这有助于你找到答案/解决方案,我会说是的,但没有硬性规定。