繁体   English   中英

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

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

我的程序有问题。 我创建了一个服务,该服务正在使用NLOG记录其操作。 在此服务旁边,我创建了一个工具来捕获此日志记录并将其显示给用户。 此连接基于WSDualHTTPBinding。

除了服务的动作,我还记录了[System.Net],[System.ServiceModel]和[System.Windows]以获得完整的日志报告。

现在,我收到TimeOutException:无法在分配的超时时间00:01:00内传输消息。 可靠通道的传输窗口中没有可用空间。 等等...

我发现,当System.Net。*的LogLevel设置为Trace时,将引发此异常。 否则不会引发异常。

我尝试了多种解决方案,例如增加超时; 设置DefaultConnectionLimit; 设置ServiceBehaviorAttribute等。 他们都没有为我工作...

有人可以帮我吗?


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();
    }
}

接口服务:

[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);
}

实施服务:

[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();
}

实现监听器:

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侦听器:

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客户端:

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());
        }
    }
}

问题是无限循环。 这是由System.Net类创建的,因为当我调用Callback函数时,System.Net名称空间正在使用http消息跟踪对下一个服务器的调用。 这被记录并发送到记录器等,等等,等等。

暂无
暂无

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

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