使用VB.Net (框架版本4.5.1)
我有一个程序,它设置了(System.Threading.Tasks.Task)任务列表,执行如下(只显示了相关代码):
po = New System.Threading.Tasks.ParallelOptions()
po.MaxDegreeOfParallelism = 5
Parallel.ForEach( task_list, po, AddressOf do_work )
该程序运行良好,但我希望添加一个日志文件,而不是只使用Console.WriteLine()
在do_work() Sub中,我希望写入日志文件,例如:
Sub do_work( param As String )
Dim thread_id as String = "Thread ID " & System.Threading.Thread.CurrentThread.ManagedThreadId.ToString() & ": "
joblog_append( thread_id & "Beg" )
joblog_append( thread_id & "param = " & param )
joblog_append( thread_id & "End" )
End Sub
理想情况下,我希望创建三个功能,例如:
joblog_open()在程序开始时打开一个日志文件。
joblog_append()追加到日志文件;可在任何任务中调用
joblog_close()关闭日志文件
当在不同线程上执行的多个任务调用joblog_append()时,实现这种日志记录的正确方法是什么?
到目前为止,我尝试过的所有尝试似乎都失败了;有时数据被写入输出文件,有时不是。
任何建议(或更好的,一个代码示例)将是最感激的。
提前谢谢。
发布于 2016-06-04 22:18:10
我认为您所遇到的问题是因为多个线程同时访问文件。
更好的方法是确保一次只访问一个线程。您可以使用锁(请参阅this SO)或将要写入字符串的concurrentQueue中的消息追加,然后在另一个线程上处理该队列。
joblog_append调用_Logger.Log,后者依次为消息排队并启动一个新线程来处理队列。
private _Logger as new Logger
Private Sub joblog_append(Message As String)
_Logger.Log(Message)
End Sub
记录器类执行以下操作。
如果任务已经创建,则消息将排队,任务本身中的While条件应该负责处理在运行过程中添加的任何消息。
'Missing: Idisposable, Fileaccess.Shared,
'TODO: remove debugger.break
Public class Logger
Public Property Messages As new ConcurrentQueue(Of string)
private _WorkerTask as Task
private event WorkerTaskCompleted
private _Stream as FileStream
private _Writer as StreamWriter
Public sub New()
_Stream = io.file.OpenWrite("Mylog.txt")
_Writer = New StreamWriter(_Stream)
End sub
Public sub Log(Message as string)
Messages.Enqueue(Message)
if _WorkerTask Is Nothing
_WorkerTask = New Task(sub()
While Messages.Any
Dim CurrentMessage as string = ""
if Messages.TryDequeue(CurrentMessage)
_Writer.WriteLine(CurrentMessage)
else
debugger.Break
End If
End While
_Writer.Flush
_Stream.Flush
RaiseEvent WorkerTaskCompleted
End Sub)
_WorkerTask.Start
End If
End sub
Private Sub Logger_WorkerTaskCompleted() Handles Me.WorkerTaskCompleted
_WorkerTask = Nothing
End Sub
End Class
请注意。这是我解决这个问题的方法,但我没有任何类似的实现和测试。因此,您必须进行测试,以确认它是否正常工作。
https://stackoverflow.com/questions/37638323
复制相似问题