下面是一个示例程序(您将需要Enterprise库来运行它)。我在循环中运行100个任务,他们将一些消息记录到事件日志中。我将生成的任务存储在任务数组中,并在一个while循环内简单地监视它。在任务循环中获取处置对象EnterpriseLibrary LogWriter错误
问题是100,随机任务失败,并给出以下错误。从我的理解任务有他们自己的状态,所以他们不应该互相干扰和记录器方法是静态的,所以我不知道我的对象被放置在哪里。
为什么Logger对象被放置,如果它的静态?
如果我把LOCK(对象)放在Task.Run()内部的记录器代码中,它可以正常工作。这是一个好主意吗 ?
错误
在Microsoft.Practices.EnterpriseLibrary.Logging.LogWriter.get_SyncLock() 在Microsoft.Practices.EnterpriseLibrary.Logging.LogWriter.ExecuteReadOperation(动作readOperation) 微软(LogEntry日志) (位于c:\ tfs \ Report \ Log.log中)中的WW.Test.TasksLoggingTest.b__1(LogEntry日志) (日志记录日志) (位于Microsoft.Practices.EnterpriseLibrary.Logging.Logger.Write WWTest \ TasksLoggingTest.cs:第7行9 在System.Threading.Tasks.Task`1.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;
}
}
}
}
看来你不可能有两个作家完全同时写入日志。您可能需要同步访问权限(正如您发现的那样)以避免争用。顺便说一句,你正在做的很多事情都可以通过延续(完成或失败等)和Task.WhenAll来完成。 –
叶似乎是这样......我不想做Task.WhenAll,因为在我的生产代码中,我们通过监视状态来做某件事。 – Zeus