我已经使用异步工作流在F#中编写了一个应用程序。 现在我想要做的是添加一些追踪到它!在多线程环境中使用TraceSource
基本上有一个类A可以多次实例化。每个实例都是独立工作的,并且是异步的(本身)和并行的(对其他人)。 我现在的基本想法是为A的每个实例添加一个TraceSource实例,这很可能是我想要做的。我设法如果每个TraceSource实例给出了相同的名称通过https://github.com/matthid/fsharpasynctrace
然而,解决分配与异步对象TraceSource的问题,其中一些将被写在同一个文件(log.txt的)和其他人将写入{guid} log.txt。
如果我给每个实例的其他名称的用户编辑app.config文件,以获得正确的记录。 A的每个实例都有一个由用户给出的逻辑名称,所以理想情况下我会将该实例的日志保存在name_log.txt中。 (这是因为用户基本上是在运行时创建A的实例)
所以我的问题是:是否有更好的方式来做到这一点,即没有用户交互,仍然获得所需的输出和灵活性(通过应用程序。配置)?
注:由于基本上一切都在线程池,并且因为可以有很多在同一时间跨实例的操作,跟踪类或线程是不是一种选择,在所有。
注2:我能想到以某种方式扩展在app.config,做我自己,这是我唯一的选择?
编辑: 为了使问题更加清晰:
想象一下下面的类:
module OtherModule =
let doSomethingAsync m = async{return()}
[<AbstractClass>]
type A (name:string) as x =
let processor =
MailboxProcessor.Start(
fun inbox -> async {
while true do
let! msg = inbox.Receive()
do! x.B(msg)
do! OtherModule.doSomethingAsync(msg)})
abstract member B : string -> Async<unit>
member x.Do(t:string) = processor.Post(t)
你有很多此类的实例,并且每个实例都住得很长。你现在有上面描述的情况。 (你也想跟踪抽象成员,这可以通过受保护的跟踪源来完成......这在F#中是不可用的,而且你想跟踪一些模块函数,这就是为什么我选择了上述分布模型。它会以任何其他方式通过日志很难)
我仍然在考虑这个解决方案... 如果我设法改变它,以便我可以在app.config中更改目录,我会将其标记为答案(尽管这可能需要一些时间)。有两件事:首先,我想使用id作为实例本身(因为它们运行时间很长),secound我认为这不是线程安全的,因为setOutput可以在执行“base”之前由两个线程调用。呼叫。我想你也许能够让我走上正轨。 – matthid 2012-07-09 17:27:19
您可以使用['initializeData'](http://msdn.microsoft.com/en-us/library/hfaf9h0e.aspx)属性在.config文件中指定目录。我不确定我了解你使用id作为实例的含义。这已经是它的工作方式了。我相信'TraceSource'在调用侦听器方法之前获得一个锁,这将使它成为线程安全的。如果情况并非如此,我会将'base'调用包装在一个lambda中,并将其传递给'setOutput',以便可以在'writers'的同一个锁中调用它。 – Daniel 2012-07-09 18:52:34
想想吧,如果'TraceSource'序列化对'TraceListener'的调用,'writers'上的锁定可以被删除。 – Daniel 2012-07-09 19:07:18