4

我正在编写一个审计文件,该文件在每个用户使用我的应用程序时为每个用户编写用户名、时间和应用程序中几个变量的旧/更改值。它使用FileStreamandStreamWriter来访问审计文件。每个用户的所有审核都将写入同一个文件。

问题是当两个用户同时更新此审计文件时,每个变量的“旧值”在用户之间混合。为什么会这样,如何解决这里的并发问题?

一些代码,为了简洁而缩短......

Dim fs As FileStream
Dim w As StreamWriter

Public Sub WriteAudit(ByVal filename As String, ByVal username As String, ByVal oldAddress As String, ByVal newAddress As String, ByVal oldCity As String, ByVal newCity As String)
    Dim now As DateTime = DateTime.Now
    Dim audit As String = ""
    audit += now + "," + username + "," + oldAddress + "," + newAddress + "," + oldCity + "," + newCity

    fs = New FileStream(filename, FileMode.Append)
    w = New StreamWriter(fs)
    w.WriteLine(audit)
    w.Close()
    fs.Close()
End Sub

这存在于 AuditLogger 类中,该类通过实例变量引用(每次访问函数时重新分配)。

4

3 回答 3

2

你可以试试这个:

TextWriter tw = TextWriter.Synchronized(File.AppendText(filePath));

File.AppendText() 方法返回一个 StreamWriter 对象,TextWriter.Synchronized() 方法将其包装以创建一个线程安全的 TextWriter,它可以像 StreamWriter 一样使用。

于 2009-12-10T18:16:15.477 回答
2

重构应用程序,这样您就不必AuditLogger每次都创建该类的新实例。直接使用单例模式,或者使用依赖注入框架在整个应用程序中使用相同的实例。

从那里开始,实现要容易得多:用lock语句包围写操作,或者使用TextWriter.Synchronized罗伯特的回答中提到的。

这篇文章可能是相关的:

于 2009-12-10T19:03:09.987 回答
0

几种方法:

首先,使用共享数据库而不是文件。即使是简单的访问数据库也可以比磁盘上的文件更优雅地处理多个用户。

其次,您可以为每个用户使用单独的文件吗?也许将其存储在他们的 %APPDATA% 文件夹中?或者也许在某个地方的网络共享上?

于 2009-12-10T17:35:21.630 回答