我有一个在服务器上托管WCF服务的Windows服务。我正在使用InstanceContextMode.PerSession
属性。这些服务可以很好地满足我的要求。
我现在想要为WCF服务实现视觉反馈,比如记录器,最好是在Windows窗体的列表框中。我希望所有客户的所有电话和随后的行动都以这种形式记录下来。我读到拥有服务的UI并不是一个好主意。有人能指出我的方向,以线程安全的方式实现这一目标。
答案 0 :(得分:4)
我认为最简单的答案是this one。 基本上你可以做的是为你的wcf服务定义一个自定义跟踪监听器。您可以修改示例以获得所需的结果。
自定义跟踪实施如下所示:
namespace WcfTrace.Trace
{
public class WebTraceListener : TraceListener
{
public override void Write(string message)
{
//write you custom code here
Debug.WriteLine(message);
}
public override void WriteLine(string message)
{
//write your custom code here
Debug.WriteLine(message);
}
}
}
服务主机上的配置必须包含以下内容:
<system.diagnostics>
<sources>
<source name="System.ServiceModel" switchValue="Information, ActivityTracing" propagateActivity="true">
<listeners>
<add name="xml" />
</listeners>
</source>
<source name="System.ServiceModel.MessageLogging">
<listeners>
<add name="xml" />
</listeners>
</source>
</sources>
<sharedListeners>
<add name="xml" type="WcfTrace.Trace.WebTraceListener,WcfTrace.Trace" />
</sharedListeners>
</system.diagnostics>
<system.serviceModel>
<diagnostics>
<messageLogging
logEntireMessage="true"
logMalformedMessages="false"
logMessagesAtServiceLevel="true"
logMessagesAtTransportLevel="false"
maxMessagesToLog="300000"
maxSizeOfMessageToLog="200000"/>
</diagnostics>
</system.serviceModel>
我个人喜欢这个想法,来自客户端的独立跟踪器(你提到的列表框的app)可以使用来自这个自定义跟踪实现的信息,以及将来可以做的任何事情。
答案 1 :(得分:1)
服务没有UI,但主机可能。
这只是一个控制台主机,但它显示来自服务的文本。
服务中的那些Console.WriteLine显示在主机中。
namespace MagicEightBallServiceHost
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("**** Console Based WCF Host *****");
using (ServiceHost serviceHost = new ServiceHost(typeof(MagicEightBallService)))
{
serviceHost.Open();
Console.WriteLine("The service is running");
Console.ReadLine();
}
[ServiceBehavior (InstanceContextMode=InstanceContextMode.PerSession)]
public class MagicEightBallService : IEightBall, IDisposable
{
private DateTime serviceStartTime;
public void Dispose()
{
Console.WriteLine("Eightball dispose ... " + OperationContext.Current.SessionId.ToString() + " " + serviceStartTime.ToLongTimeString());
}
public MagicEightBallService()
{
serviceStartTime = DateTime.Now;
Console.WriteLine("Eightball awaits your question " + OperationContext.Current.SessionId.ToString() + " " + serviceStartTime.ToLongTimeString());
}
public string ObtainAnswerToQuestion(string userQuestion)
{
Console.WriteLine("Eightball ObtainsAnser " + OperationContext.Current.SessionId.ToString() + " " + serviceStartTime.ToLongTimeString());
return "maybe " + OperationContext.Current.SessionId.ToString() + " " + serviceStartTime.ToLongTimeString() ;
}
答案 2 :(得分:1)
你所说的基本上是你的Windows服务中的WCF服务在发生“有趣”的事情时向UI前端提供事件通知。幸运的是,Publish-Subscribe Framework的作者Juval Lowy开发了Programming WCF Services。详细信息在this excellent MSDN article中介绍,源代码可在Lowy's website免费获取。
这个框架的巧妙之处在于它将发布者(例如,Windows服务中的WCF服务)与任何订阅者(例如GUI)分离。发布者“发布”Pub / Sub服务感兴趣的事件,该事件始终可用。从发布者的角度来看,是否有任何订阅者并不重要。发布/订阅服务负责将事件路由到任何和所有注册订阅者。通过这种方式,Windows服务中的WCF服务会在事件发生时发布,GUI将在加载/退出时订阅/取消订阅发布/订阅服务,并且发布/订阅服务将在事件发生时通知您的GUI。 / p>
我在我的项目中使用过此设置,效果非常好。
编辑: 我理解您希望拥有自己的UI,以显示来自Windows服务托管的WCF服务的事件。另一种选择是利用可从Windows本机事件查看器(eventvwr.msc)访问的应用程序日志。如果这种方法可以接受,请查看我的说明here,了解如何从Windows服务进行设置。
答案 3 :(得分:0)
使用log4net之类的内容记录您要显示的信息,该信息代表您感兴趣的Web服务活动。通过使用log4net,您只需更改配置文件即可过滤记录的信息类型。您还可以通过登录配置文件来更改信息的位置和方式。您可以为log4net配置的其中一个appender是SysLogAppender。这会将日志信息发送到远程SysLog Server(它也可以与Web服务一起部署)。有许多SysLog服务器可用,如Kiwi,它们将提供日志事件的滚动显示,并提供某些事件的过滤器和操作(例如:发生错误时向管理员发送电子邮件)。还有open source SysLog Severs可用。这有效地将日志信息的查看和处理与实际日志记录分离。