下面是一个示例程序(您需要Enterprise库来运行它)。我在循环中运行100个任务,他们将一些消息记录到事件日志中。我将生成的Task存储在Task数组中,并简单地在while循环中监视它。
问题是满分100分,随机任务失败,给出如下错误。从我的理解任务有自己的状态,所以他们不应该相互干扰,Logger方法是静态的,所以我不知道我的对象在哪里被处置。
-
如果Logger对象是静态的,为什么会被处理?
-
如果我把锁(对象)围绕我的日志代码在Task.Run()比它工作得好。
在Microsoft.Practices.EnterpriseLibrary.Logging.LogWriter.get_SyncLock ()在Microsoft.Practices.EnterpriseLibrary.Logging.LogWriter。readOperation ExecuteReadOperation(行动)在Microsoft.Practices.EnterpriseLibrary.Logging.LogWriter。写(LogEntry日志)在Microsoft.Practices.EnterpriseLibrary.Logging.Logger。写(LogEntry日志)在c:tfsReportWWTestTasksLoggingTest.cs:第79行1. System.Threading.Tasks.Task"innerinvoke ()在System.Threading.Tasks.Task.Execute ()
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Practices.EnterpriseLibrary.Logging;
using System.Web.Hosting;
namespace Test
{
public class TasksLoggingTest
{
bool flag = true;
Thread T;
public static volatile bool IsWorkStarted = false;
public void Start()
{
while(flag)
{
try
{
if (IsWorkStarted == false)
{
IsWorkStarted = true;
T = new Thread(DoWork);
T.IsBackground = true;
T.Start();
}
}
catch(Exception e)
{
Console.WriteLine("Error starting thread");
}
finally
{
Thread.Sleep(TimeSpan.FromSeconds(5));
}
}
}
public void DoWork()
{
try
{
Task<int>[] _tempTaskList = new Task<int>[100];
for (int i = 0; i < 100; i++)
{
int localI = i;
_tempTaskList[localI] = Task.Run(() =>
{
Logger.SetLogWriter(new LogWriterFactory().Create(), false);
var logEntry = new LogEntry
{
Severity = TraceEventType.Information,
Message = "Job Started :",
};
logEntry.Categories.Clear();
logEntry.Categories.Add("Send.To.EventLog");
Logger.Write(logEntry);
return 0;
});
}
bool IsAnyTaskPending = true;
int noOfTasks = 0;
while (IsAnyTaskPending == true)
{
foreach (var t in _tempTaskList)
{
// Remove Completed Tasks from TaskList
if (t != null && t.Status == TaskStatus.RanToCompletion)
{
Task<int> completedTask = t;
var temp = _tempTaskList.ToList();
//temp.Remove(t);
//_tempTaskList = temp.ToArray();
noOfTasks++;
//Console.WriteLine(" Completed");
}
else if (t != null && t.Status == TaskStatus.Faulted)
{
Console.WriteLine(" Failed");
}
}
if (_tempTaskList.Length == 0)
{
IsAnyTaskPending = false;
Console.WriteLine("All {0} Tasks Done", noOfTasks);
}
}
IsWorkStarted = false;
}
catch(Exception e)
{
throw;
}
}
}
}
问题是每个任务都调用Logger.SetLogWriter
。内部的LogWriter
是单例的。然而,当您调用SetLogWriter
时,当前内部的LogWriter
被处理:
public static void SetLogWriter(LogWriter logWriter, bool throwIfSet = true)
{
Guard.ArgumentNotNull(logWriter, "logWriter");
var currentWriter = writer;
if (currentWriter != null && throwIfSet)
{
throw new InvalidOperationException(Resources.ExceptionLogWriterAlreadySet);
}
writer = logWriter;
if (currentWriter != null)
{
currentWriter.Dispose();
}
}
所以每个任务都在处理单例LogWriter
,它正在从其他任务下拉出rug。解决方案是在调用任务之前引导SetLogWriter
一次。