![](/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.