簡體   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