我已經使用異步工作流在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