任务并行库和跟踪侦听器跟踪列表未被调用

时间:2018-05-09 15:28:20

标签: c# task-parallel-library trace

所以我有一个循环的任务,一切正常并且正确记录

但是在我放了一个Parallel.ForEach后,我的日志记录就被破坏了。

我有一个自定义跟踪侦听器,它接收跟踪消息并将int放入一个已处理的缓冲区以及记录。

并行后,

不再调用跟踪侦听器。 (输出行是Trace.WriteLine的包装,并添加了trace和flush内容以试图解决问题.Trace.AutoFlush已经= true ...)

代码中的测试代码

Parallel.ForEach( allStudentsInAd, ( StudentPortalNightly.CV.AllAdStudentsCV adStudent )  =>
{
    OutputLine( "*********before" );
    //AddUserToListIfNotCorrectlyTied( allStudentsInCdssDict, studentsAlreadyTiedDict, adStudent, ref cachedAllStudentsToBeTied, ref allStudentsInAd );
    OutputLine( "*********after" );
    Trace.Flush();
});

每个请求并行化之前的代码(它是一个foreach)

        foreach ( StudentPortalNightly.CV.AllAdStudentsCV adStudent in allStudentsInAd )
        {
            AddUserToListIfNotCorrectlyTied( allStudentsInCdssDict, studentsAlreadyTiedDict, adStudent, ref cachedAllStudentsToBeTied, ref allStudentsInAd );
        }

听者

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using JCDCHelper.Extension;
using JCDCHelper.Logging.Interfaces;
using JCDCHelper.Utilities.Interfaces;
using StructureMap;

namespace StudentPortalNightly.Utilities
{
    public class SpnCustomListener:TextWriterTraceListener
    {
        private INetLog log = ObjectFactory.GetInstance< INetLog >();

        private Object slLock = new Object();

        private List < string > sl = null;

        /// <summary>
        /// Sets the string list.
        /// </summary>
        /// <param name="_sl">The _SL.</param>
        public void SetStringList( List<string> _sl )
        {
            sl = _sl;
        }

        /// <summary>
        /// Gets the string list.
        /// </summary>
        /// <returns></returns>
        public List<string> GetStringList()
        {
            return sl;
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="SpnCustomListener"/> class.
        /// </summary>
        public SpnCustomListener()
        {
            base.Name = "TraceOutputCustom.txt";
        }

        /// <summary>
        /// Writes the value of the object's <see cref="M:System.Object.ToString"/> method to the listener you create when you implement the <see cref="T:System.Diagnostics.TraceListener"/> class, followed by a line terminator.
        /// </summary>
        /// <param name="o">An <see cref="T:System.Object"/> whose fully qualified class name you want to write.</param>
        public override void WriteLine( object o )
        {
            WriteLine( o == null ? "" : o.ToString() );
        }

        /// <summary>
        /// Writes a message to this instance's <see cref="P:System.Diagnostics.TextWriterTraceListener.Writer"/> followed by a line terminator. The default line terminator is a carriage return followed by a line feed (\r\n).
        /// </summary>
        /// <param name="message">A message to write.</param>
        /// <PermissionSet>
        ///     <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true"/>
        /// </PermissionSet>
        public override void WriteLine( string message )
        {
            log.Debug("WriteLine()..."+ message );
            message = DateTime.Now.ToString() + " " + message;
            //base.Write( " " );
            base.WriteLine( message );

            if ( null != sl )
            {
                lock( slLock )
                {
                    sl.Add( message );
                }
                Console.WriteLine( message );// so it will log in console mode too - EWB
            }
            else
            {
                log.Debug( "SpnCustomListener string buffer is null" );
            }
        }
    }
}

它们都是作为Threadlocal创建的吗?

我需要做些什么才能让各个线程登录到跟踪侦听器?

1 个答案:

答案 0 :(得分:1)

很难说,因为根据您发布的代码,无法确定您的收听者可能会被调用的位置。但是,您遇到的一个问题是:

public class SpnCustomListener:TextWriterTraceListener
{
    private INetLog log = ObjectFactory.GetInstance< INetLog >();

    private Object slLock = new Object();

    private List <string> sl = null;

因为您的slLock对象是私有的,所以它将在每个类的实例中创建,因此它不会跨线程工作;试试这个:

public class SpnCustomListener:TextWriterTraceListener
{
    private INetLog log = ObjectFactory.GetInstance< INetLog >();

    private static Object slLock = new Object();

    private List <string> sl = null;