我已经阅读了 Microsoft 页面上有关 Windows 平台上进程间通信的文档,因此我开始做一些演示项目来测试它是如何工作的等。因为我想做的就是将一些文件从 Windows 共享从本地网络复制到我决定选择
WPF
作为 GUI 和一些“其他”方法来完成逻辑工作。
我的想法是实现GUI和Windows Service之间的成功通信。在 MSDN 上,我在堆栈上的其他帖子中阅读并发现最好的方法是使用 Windows Communication Foundation。
问题:
通讯已建立。我已经准备好了一个正在运行的端点。返回一小部分数据是可以的,但是当执行一些更复杂的操作(例如循环遍历 NFS 共享或目录中的某些文件)时,则会抛出异常
'There was an error reading from the pipe: The pipe has ended. (109, 0x6d).'
。
这是我的项目结构(4个解决方案):
DirToCopy
、Windows 服务和 WCFService:
<system.serviceModel>
<services>
<service name="WCFService.MyService">
<endpoint address="net.pipe://localhost/copy" binding="netNamedPipeBinding"
bindingConfiguration="" contract="WCFService.IMyService" />
</service>
</services>
</system.serviceModel>
Windows服务:
protected override void OnStart(string[] args)
{
if (serviceHost != null)
{
serviceHost.Close();
}
serviceHost = new ServiceHost(typeof(MyService));
serviceHost.Open();
}
protected override void OnStop()
{
if (serviceHost != null)
{
serviceHost.Close();
serviceHost = null;
}
}
WCF服务:
[ServiceContract]
public interface IMyService
{
//In SharedClasses solution. Included in using.
[OperationContract]
MyServiceSettings GetSettings();
//In SharedClasses solution. Included in using.
[OperationContract]
List<DirToCopy> GetDirs();
}
public class MyService : IMyService
{
// SharedClasses lib
private MyServiceSettings Settings;
// SharedClasses lib
private DirToCopyService DirService;
public MyService()
{
Settings = new MyServiceSettings();
DirService = new DirService(Settings);
}
public MyServiceSettings GetSettings()
{
return Settings;
}
public List<DirToCopy> GetDirs()
{
return DirService.GetDirs();
}
}
共享类库:
public class DirToCopyService
{
private MyServiceSettings _Settings;
public List<DirToCopy> dirs;
public DirToCopyService() { }
public DirToCopyService(MyServiceSettings Settings)
{
_Settings = Settings;
}
public List<DirToCopy> GetDirs()
{
DirectoryInfo directoryInfo = new DirectoryInfo(_Settings.nfsAddress);
FileInfo[] files = directoryInfo.GetFiles("*.txt");
dirs = new List<DirToCopy>();
foreach(FileInfo file in files)
{
DirToCopy dirToCopy = new DirToCopy();
dirToCopy._filename = file.FullName;
dirToCopy._size = new System.IO.FileInfo(Path.Combine(_Settings.nfsAddress, file.FullName)).Length;
dirs.Add(DirToCopy);
}
return dirs;
}
}
图形用户界面:
public class ServiceClient
{
private IMyService _serviceProxy;
private ChannelFactory<IMyService> _channelFactory;
private const string NamedPipeAddress = "net.pipe://localhost/copy";
public ServiceClient()
{
_channelFactory = new ChannelFactory<IMyService>(new NetNamedPipeBinding(), new EndpointAddress(NamedPipeAddress));
_serviceProxy = _channelFactory.CreateChannel();
}
public MyServiceSettings GetSettings()
{
return _serviceProxy.GetSettings();
}
public List<DirToCopy> GetDirs()
{
return _serviceProxy.GetDirs();
}
}
GetDirs()
的按钮单击并抛出“管道”错误。总结: GUI 初始化后,
MyServiceSettings
已正确传递给它,我可以在 GUI 中使用此类的任何属性。但是当我想做一些更复杂的事情,比如检索 List<DirsToCopy>
时,在专用于 Click
方法的操作处理之后,就会出现错误:'There was an error reading from the pipe: The pipe has ended. (109, 0x6d).'
。
我不知道这是否是由于传递的数据大小或任何其他设置引起的。我也不确定我的方法是否正确或者我应该改变它。有人有类似问题吗
如果它适用于较小部分的数据,您可以尝试增加绑定的一些配额,例如:
<system.serviceModel>
<bindings>
<netNamedPipeBinding>
<binding name="netNamedPipeBinding" maxBufferSize="2147483647" maxReceivedMessageSize="2147483647" maxBufferPoolSize="2147483647" />
</netNamedPipeBinding>
</bindings>
<services>
<service name="WCFService.MyService">
<endpoint address="net.pipe://localhost/copy" binding="netNamedPipeBinding"
bindingConfiguration="netNamedPipeBinding" contract="WCFService.IMyService" />
</service>
</services>
</system.serviceModel>
您可能还想更改传输模式: