调用同一实例的两个方法将触发 WCF 中的 Dispose 方法



我面临着一个奇怪的情况。我可能对此不太了解,我需要一些澄清。

我使用 WCF 做一些打印工作。以下是呈现我的问题的最小代码片段。

周转基金服务

[ServiceContract]
public interface IPrintLabelService
{
    [OperationContract]
    bool Generate(string templateFullFilename, Dictionary<string, string> textFields, Dictionary<string, string> imageFields);
    [OperationContract]
    bool Print(string printerName);
}
public class PrintLabelService : IPrintLabelService, IDisposable
{
    private WordWrapper _wordWrapper;
    public PrintLabelService()
    {
        _wordWrapper = new WordWrapper();
    }
    public bool Generate(string templateFullFilename, Dictionary<string, string> textFields, Dictionary<string, string> imageFields)
    {            
        return _wordWrapper.Generate(textFields, imageFields);            
    }
    public bool Print(string printerName)
    {
        return _wordWrapper.PrintDocument(printerName);                
    }
    public void Dispose()
    {
        if (_wordWrapper != null)
        {
            _wordWrapper.Dispose();
        }
    }
}

单元测试

public void PrintLabelTestMethod()
{
    ILabel label = null;
    try
    {
        //some stuff
        // ...
        // Act
        label.Generate();            
        label.Print(printerName);    
    }
    finally
    {
        label.Dispose();
    }
}

标签分类

class Label : ILabel
{
    private readonly PrintLabelServiceClient _service;
    private bool _disposed = false;
    public Label(string templateFullFileName)
    {
        _service = new PrintLabelServiceClient();
    }
    public bool Generate()
    {   
        return _service.Generate(TemplateFullFileName, textFields, imageFields);
    }        
    public bool Print(string printerName)
    {
        return _service.Print(printer.Name);
    }         
}

调用时(单元测试部分(

label.Generate();            

然后

label.Print(printerName);    

服务中的 Dispose 方法被调用两次(对于上述每个调用(。然后_wordWrapper被重新初始化,这会破坏其状态。

为什么每次调用都调用 Dispose,以及如何防止 Dispose 被调用两次?

在您的用例中,您需要让服务使用InstanceContextMode.PerSession。使用basicHttpBinding时似乎不支持此功能(请参阅此处的示例(。

由于您使用的是basicHttpBinding,因此服务将使用InstanceContextMode.PerCall。这意味着将为对服务的每个传入调用创建一个新的PrintLabelService实例。当然,为label.Print(printerName);调用创建的新实例不会看到用于label.Generate();调用的实例中_wordWrapper的局部变量。

为了使此功能正常工作,您需要切换到使用支持 InstanceContextMode.PerSession 的其他绑定。也许是wsHttpBinding

相关内容

  • 没有找到相关文章