![](/img/trans.png)
[英]Using TextWriter with StreamWriter and Reading/Writing Simultaneously
[英]StreamWriter/Reader reading and then immediately writing causes exception
我需要從文件中讀取一個數字,然后遞增該數字並更新同一文件,僅用於調試目的。 我編寫了這段代碼,令我驚訝的是,它引發了一個異常(它僅用於調試,但是我還是想深入了解一下):
該進程無法訪問文件”,因為它正在被另一個進程使用。
碼:
string path = Server.MapPath("~/Log.txt");
int newTotal = 0;
using (var reader = new StreamReader(path))
{
var total = reader.ReadLine();
if (total != null)
{
newTotal = int.Parse(total) + 1;
}
}
using (var writer = new StreamWriter(path, false))
{
// I added AutoFlush because I read somewhere on SO
// this will write to disk immediately
writer.AutoFlush = true;
writer.Write(newTotal);
}
然后我想把問題縮小到閱讀或寫作上,所以我這樣做了:
string path = Server.MapPath("~/Log.txt");
int newTotal = 0;
try
{
using (var reader = new StreamReader(path))
{
var total = reader.ReadLine();
if (total != null)
{
newTotal = int.Parse(total) + 1;
}
}
}
catch (Exception)
{
throw new System.Web.HttpException("During reading...");
}
try
{
using (var writer = new StreamWriter(path, false))
{
writer.AutoFlush = true;
writer.Write(newTotal);
}
}
catch (Exception)
{
throw new System.Web.HttpException("During writing...");
}
我得到這個,所以這告訴我這是在兩個過程中隨機發生的:
During reading...
During writing...
During reading...
During writing...
During reading...
During reading...
During writing...
During writing...
During writing...
During writing...
During writing...
During reading...
During reading...
During reading...
請注意,此代碼在此方法中的MVC應用程序的Controller
中:
protected override void Initialize(RequestContext requestContext)
{
base.Initialize(requestContext);
// Code is here
}
我使用了Process Explorer ,其他都沒有使用該文件。
問題 :我在這里放置東西,為什么要例外?
起初,我認為也許在配置reader
存在延遲,但是在這種情況下,所有例外都應與reader
有關,但事實並非如此。 另外,下面還將給出相同的例外:
this.path = Server.MapPath("~/Log.txt");
var total = System.IO.File.ReadAllText(this.path);
int newTotal = 0;
if (total != null)
{
newTotal = int.Parse(total) + 1;
}
System.IO.File.WriteAllText(this.path, newTotal.ToString());
沒有線程。 僅HTTP GET(常規和通過AJAX)。
編輯
在使用Visual Studio 2015進行負載測試期間,會發生這種情況。
我遇到了這個問題,並通過添加while循環解決了這個問題。
嘗試這樣做,看看是否能解決您的問題。
using (var reader = new StreamReader(path))
{
while (reader.Peek() > -1)
{
var total = reader.ReadLine();
newTotal = int.Parse(total) + 1;
}
}
問題不在於:
reader
之前達到寫入狀態。 我使用控制台應用程序測試了確切的代碼,並且該問題無法復制。 static
),那么它們顯然將不是線程安全的。 他們將被共享。 但是此代碼不在靜態上下文中。 注意事項:
使用瀏覽器時,從未復制此問題。 我還做了一些簡單的事情,像這樣:
protected override void Initialize(RequestContext requestContext)
{
System.IO.File.AppendAllText(tPath, "Thread enter and ID is: " +
System.Threading.Thread.CurrentThread.ManagedThreadId + Environment.NewLine);
// Placed all code here
System.IO.File.AppendAllText(tPath, "Thread exit and ID is: " +
System.Threading.Thread.CurrentThread.ManagedThreadId + Environment.NewLine);
}
現在有了上面的代碼,當按預期通過瀏覽器發出請求時,文件的內容如下所示。 注意每個條目都是同步的 :
Thread enter and ID is: 35
Thread exit and ID is: 35
Thread enter and ID is: 11
Thread exit and ID is: 11
Thread enter and ID is: 29
Thread exit and ID is: 29
Thread enter and ID is: 36
Thread exit and ID is: 36
Thread enter and ID is: 27
Thread exit and ID is: 27
Thread enter and ID is: 11
Thread exit and ID is: 11
Thread enter and ID is: 29
Thread exit and ID is: 29
Thread enter and ID is: 8
Thread exit and ID is: 8
Thread enter and ID is: 11
Thread exit and ID is: 11
Thread enter and ID is: 36
Thread exit and ID is: 36
...
但是在Visual Studio負載測試期間,內容是這樣的,並且該方法的條目不是同步的 :
Thread enter and ID is: 12
Thread exit and ID is: 12
Thread enter and ID is: 29
Thread enter and ID is: 49
Thread enter and ID is: 51
Thread exit and ID is: 29
Thread exit and ID is: 51
Thread enter and ID is: 48
Thread exit and ID is: 48
Thread enter and ID is: 57
Thread exit and ID is: 57
Thread enter and ID is: 17
Thread exit and ID is: 17
Thread enter and ID is: 55
Thread exit and ID is: 55
Thread enter and ID is: 42
Thread exit and ID is: 42
Thread enter and ID is: 47
Thread enter and ID is: 55
...
結論
總之,使用Visual Studio進行負載測試時,調用行為與從瀏覽器中獲得的調用行為並不完全相同。 由於某種原因,每個線程都沒有獲得其自己的類實例。 我不知道為什么,但是如果有人這樣做,請發出提示。如果您問我,這就是廢話: 如果它所做的工作完全違背ASP.NET架構,該如何進行負載測試?
1. 線程安全ASP.NET
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.