简体   繁体   English

在跟踪级别登录System.Net时分配的超时

[英]Allotted timeout while logging System.Net on Trace level

I'm having an issue with my program. 我的程序有问题。 I've created a service which is logging its actions with NLOG. 我创建了一个服务,该服务正在使用NLOG记录其操作。 Next to this service I've created a tool to catch this logging and show it to the user. 在此服务旁边,我创建了一个工具来捕获此日志记录并将其显示给用户。 This connection is based on WSDualHTTPBinding. 此连接基于WSDualHTTPBinding。

Besides the actions of the service, I'm also logging [System.Net], [System.ServiceModel] and [System.Windows] for a complete log report. 除了服务的动作,我还记录了[System.Net],[System.ServiceModel]和[System.Windows]以获得完整的日志报告。

Now I'm getting the TimeOutException: The message could not be transferred within the allotted timeout of 00:01:00. 现在,我收到TimeOutException:无法在分配的超时时间00:01:00内传输消息。 There was nog space available in the reliable channel's transfer window. 可靠通道的传输窗口中没有可用空间。 etc... 等等...

I've found out that this exception is thrown when the LogLevel for the System.Net.* is set to Trace. 我发现,当System.Net。*的LogLevel设置为Trace时,将引发此异常。 Otherwise the exception won't be thrown. 否则不会引发异常。

I've tried multiple solutions like increasing the Timeout; 我尝试了多种解决方案,例如增加超时; setting the DefaultConnectionLimit; 设置DefaultConnectionLimit; setting the ServiceBehaviorAttribute and many more. 设置ServiceBehaviorAttribute等。 None of them worked for me... 他们都没有为我工作...

Could somebody help me with this? 有人可以帮我吗?


ConsoleApplication Service: ConsoleApplication服务:

class Program
{
    static void Main(string[] args)
    {
        IoC.Kernel.Bind<ILogging>().ToConstant(new Logging());

        try
        {
            //Normal binding
            var binding = new BasicHttpBinding();
            binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
            binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;

            var host = new ServiceHost(typeof(Contract));
            host.Description.Behaviors.Find<ServiceDebugBehavior>().IncludeExceptionDetailInFaults = true;

            var path = "http://address:port/IContract";
            host.AddServiceEndpoint(typeof(IContract), binding, path);

            host.Open();

            //Duplex binding
            var duplexBinding = new WSDualHttpBinding();
            duplexBinding.Security.Mode = WSDualHttpSecurityMode.Message;
            duplexBinding.Security.Message.ClientCredentialType = MessageCredentialType.Windows;

            var duplexHost = new ServiceHost(typeof(DuplexContract));
            duplexHost.Description.Behaviors.Find<ServiceDebugBehavior>().IncludeExceptionDetailInFaults = true;

            var duplexPath = "http://address:port/IDuplexContract";
            duplexHost.AddServiceEndpoint(typeof(IDuplexContract), duplexBinding, duplexPath);

            duplexHost.Open();
            IoC.Kernel.Get<ILogging>().Log("Listening.......");
        }
        catch (Exception ex)
        {
            IoC.Kernel.Get<ILogging>().Log(ex.ToString());
        }
        Console.ReadLine();
    }
}

Interfaces Service: 接口服务:

[ServiceContract]
public interface IContract
{
    [OperationContract]
    void Update(string i);
}

[ServiceContract(CallbackContract = typeof(IDuplexContractCallback), SessionMode = SessionMode.Required)]
public interface IDuplexContract
{
    [OperationContract(IsOneWay = true)]
    void AddListener();
}

public interface IDuplexContractCallback
{
    [OperationContract(IsOneWay = true)]
    void Logger(string obj);
    [OperationContract(IsOneWay = true)]
    void ReceivedCalculate(int i);
}

public interface ILogging
{
    void Log(string message);
    void AddObserver(Action<string> addEventLog);
}

Implementations Service: 实施服务:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class DuplexContract : IDuplexContract
{
    public void AddListener()
    {
        IoC.Kernel.Get<ILogging>().AddObserver(OperationContext.Current.GetCallbackChannel<IDuplexContractCallback>().Logger);
        IoC.Kernel.Get<ILogging>().Log("Added listener");
    }
}

[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class Contract : IContract
{
    public void Update(string i)
    {
        IoC.Kernel.Get<ILogging>().Log(string.Format("Received: {0}", i));
    }
}

public class Logging : ILogging
{
    public Logging()
    {
        if (LogManager.Configuration == null)
        {
            LogManager.Configuration = new LoggingConfiguration();
        }

        Target consoleTarget;
        consoleTarget = LogManager.Configuration.FindTargetByName(nameof(consoleTarget));
        if (consoleTarget == null)
        {
            consoleTarget = new ColoredConsoleTarget()
            {
                Layout = "${longdate} [${logger}] [${level:uppercase=true}]: ${message} ${onexception:inner=${newline} ${exception:format=ToString:maxInnerExceptionLevel=4:innerFormat=ToString:seperator=\r\n}}",
                Name = nameof(consoleTarget),
                UseDefaultRowHighlightingRules = false,
            };
            (consoleTarget as ColoredConsoleTarget).RowHighlightingRules.Add(new ConsoleRowHighlightingRule(ConditionParser.ParseExpression("level == LogLevel.Fatal"), ConsoleOutputColor.Magenta, ConsoleOutputColor.NoChange));
            (consoleTarget as ColoredConsoleTarget).RowHighlightingRules.Add(new ConsoleRowHighlightingRule(ConditionParser.ParseExpression("level == LogLevel.Error"), ConsoleOutputColor.Red, ConsoleOutputColor.NoChange));
            (consoleTarget as ColoredConsoleTarget).RowHighlightingRules.Add(new ConsoleRowHighlightingRule(ConditionParser.ParseExpression("level == LogLevel.Warn"), ConsoleOutputColor.Yellow, ConsoleOutputColor.NoChange));
            (consoleTarget as ColoredConsoleTarget).RowHighlightingRules.Add(new ConsoleRowHighlightingRule(ConditionParser.ParseExpression("level == LogLevel.Info"), ConsoleOutputColor.White, ConsoleOutputColor.NoChange));
            (consoleTarget as ColoredConsoleTarget).RowHighlightingRules.Add(new ConsoleRowHighlightingRule(ConditionParser.ParseExpression("level == LogLevel.Debug"), ConsoleOutputColor.Gray, ConsoleOutputColor.NoChange));
            (consoleTarget as ColoredConsoleTarget).RowHighlightingRules.Add(new ConsoleRowHighlightingRule(ConditionParser.ParseExpression("level == LogLevel.Trace"), ConsoleOutputColor.DarkGray, ConsoleOutputColor.NoChange));
            LogManager.Configuration.AddTarget(consoleTarget);
        }

        UpdateRules(consoleTarget);
        LogManager.ReconfigExistingLoggers();
    }

    public void Log(string message)
    {
        LogManager.GetLogger("CustomLogger").Trace(message);
    }

    private void UpdateRules(Target target)
    {
        var rules = LogManager.Configuration.LoggingRules.Where(u => u.Targets.Contains(target)).ToList();
        rules.ForEach(u => LogManager.Configuration.LoggingRules.Remove(u));

        LogManager.Configuration.LoggingRules.Add(new LoggingRule("System.Net.*", LogLevel.Trace, target)); //<-- Throws the exception
        LogManager.Configuration.LoggingRules.Add(new LoggingRule("System.ServiceModel.*", LogLevel.Trace, target));
        LogManager.Configuration.LoggingRules.Add(new LoggingRule("System.Windows.*", LogLevel.Trace, target));
        LogManager.Configuration.LoggingRules.Add(new LoggingRule("CustomLogger", LogLevel.Trace, target));
    }

    public void AddObserver(Action<string> addEventLog)
    {
        Target duplexCallbackTarget;
        duplexCallbackTarget = LogManager.Configuration.FindTargetByName(nameof(DuplexCallbackTarget));
        if (duplexCallbackTarget == null)
        {
            var layout = new XmlLayout();
            duplexCallbackTarget = new DuplexCallbackTarget()
            {
                Name = nameof(DuplexCallbackTarget),
                Layout = layout,
                CallbackAction = addEventLog,
            };
            LogManager.Configuration.AddTarget(duplexCallbackTarget);
        }
        UpdateRules(duplexCallbackTarget);
        LogManager.ReconfigExistingLoggers();
    }
}

[Target("DuplexCallback")]
public class DuplexCallbackTarget : TargetWithLayout
{
    /// <summary>
    /// The callback action from the client event viewer.
    /// </summary>
    public Action<string> CallbackAction { get; set; }

    /// <summary>
    /// Writes the specified log event information.
    /// </summary>
    /// <param name="logEventInfo">The log event information.</param>
    protected override void Write(LogEventInfo logEventInfo)
    {
        try
        {
            CallbackAction(logEventInfo.Message);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.ToString());
        }
    }
}

//Ninject
public static class IoC
{
    public static IKernel Kernel = new StandardKernel();
}

Implementation Listener: 实现监听器:

public class ContractCallback : IDuplexContractCallback
{
    public void Logger(string obj)
    {
        Console.WriteLine(string.Format("Client received: {0}", obj));
    }

    public void ReceivedCalculate(int i)
    {
        Console.WriteLine(string.Format("Client received: {0}", i));
    }
}

ConsoleWindow Listener: ConsoleWindow侦听器:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Waiting for server to be ready...");
        Console.ReadLine();

        var binding = new WSDualHttpBinding();
        binding.Security.Mode = WSDualHttpSecurityMode.Message;
        binding.Security.Message.ClientCredentialType = MessageCredentialType.Windows;

        var factory = new DuplexChannelFactory<IDuplexContract>(new InstanceContext(new ContractCallback()), binding, new EndpointAddress("http://address:port/IDuplexContract"));
        var channel = factory.CreateChannel();
        channel.AddListener();
        Console.WriteLine("Listening at server....");
        Console.ReadLine();
    }
}

ConsoleWindow Client: ConsoleWindow客户端:

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Waiting for server & listener to be ready...");
        Console.ReadLine();

        var binding = new BasicHttpBinding();
        binding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
        binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;

        var factory = new ChannelFactory<IContract>(binding, new EndpointAddress("http://address:port/IContract"));
        var channel = factory.CreateChannel();

        while (true)
        {
            channel.Update(Console.ReadLine());
        }
    }
}

The issue is an infinity loop. 问题是无限循环。 This is created by the System.Net class because when I'm calling my Callback function the System.Net namespace is tracing my call to the next server with the http message. 这是由System.Net类创建的,因为当我调用Callback函数时,System.Net名称空间正在使用http消息跟踪对下一个服务器的调用。 This is logged and sent to the logger, etc, etc, etc... 这被记录并发送到记录器等,等等,等等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM