首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >从asp.net任务异步写入日志文件

从asp.net任务异步写入日志文件
EN

Stack Overflow用户
提问于 2016-06-05 04:01:54
回答 1查看 623关注 0票数 0

使用VB.Net (框架版本4.5.1)

我有一个程序,它设置了(System.Threading.Tasks.Task)任务列表,执行如下(只显示了相关代码):

代码语言:javascript
代码运行次数:0
运行
复制
po = New System.Threading.Tasks.ParallelOptions()
po.MaxDegreeOfParallelism = 5
Parallel.ForEach( task_list, po, AddressOf do_work )

该程序运行良好,但我希望添加一个日志文件,而不是只使用Console.WriteLine()

在do_work() Sub中,我希望写入日志文件,例如:

代码语言:javascript
代码运行次数:0
运行
复制
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()时,实现这种日志记录的正确方法是什么?

到目前为止,我尝试过的所有尝试似乎都失败了;有时数据被写入输出文件,有时不是。

任何建议(或更好的,一个代码示例)将是最感激的。

提前谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-06-05 06:18:10

我认为您所遇到的问题是因为多个线程同时访问文件。

更好的方法是确保一次只访问一个线程。您可以使用锁(请参阅this SO)或将要写入字符串的concurrentQueue中的消息追加,然后在另一个线程上处理该队列。

joblog_append调用_Logger.Log,后者依次为消息排队并启动一个新线程来处理队列。

代码语言:javascript
代码运行次数:0
运行
复制
private _Logger as new Logger
Private Sub joblog_append(Message As String)
 _Logger.Log(Message)
End Sub

记录器类执行以下操作。

  • 将消息附加到并发队列
  • 创建并启动一个任务(如果没有人运行)将队列内容写入文件。
  • 完成任务后,将其设置为空

如果任务已经创建,则消息将排队,任务本身中的While条件应该负责处理在运行过程中添加的任何消息。

代码语言:javascript
代码运行次数:0
运行
复制
'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

请注意。这是我解决这个问题的方法,但我没有任何类似的实现和测试。因此,您必须进行测试,以确认它是否正常工作。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37638323

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档