Jef*_*hnn 1 asp.net-mvc asynchronous
我想 在asp.net mvc中异步写日志,代码是这样的:
public ActionResult Index()
{
byte[] buffer = Encoding.UTF8.GetBytes(string.Format("log:{0}{1}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:ffff"), Environment.NewLine));
FileStream fs = new FileStream(@"c:\log.txt", FileMode.Append, FileAccess.Write, FileShare.Write, 1024, true);
fs.BeginWrite(buffer, 0, buffer.Length, ar =>
{
fs.EndWrite(ar);
fs.Close();
}, null);
}
Run Code Online (Sandbox Code Playgroud)
但结果不是我预期的,有些日志没有记录,任何人都可以告诉我代码有什么问题
您需要确保只有一个线程正在写入该文件.如果有2个并发用户同时调用Index操作,他们可能会同时尝试写入日志文件,而第二个用户将失败.在ASP.NET等多线程应用程序中,始终确保正确同步对共享资源的访问.
同样在您的代码中,您无法防范错误.如果抛出异常怎么办?您永远不会关闭此流,第二次尝试访问它将引发异常.
因此,简化此代码的一种可能性是使用TPL:
private static object _synRoot = new object();
public ActionResult Index()
{
Task.Factory.StartNew(() =>
{
lock (_synRoot)
{
var data = string.Format("log:{0}{1}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:ffff"), Environment.NewLine)
System.IO.File.AppendAllText("log.txt", data);
}
});
return View();
}
Run Code Online (Sandbox Code Playgroud)
为了避免控制器中的噪音和污染,您可以使用动作过滤器:
public class LogAttribute : ActionFilterAttribute
{
private static object _synRoot = new object();
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
Task.Factory.StartNew(() =>
{
lock (_synRoot)
{
var data = string.Format("log:{0}{1}", DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:ffff"), Environment.NewLine)
System.IO.File.AppendAllText(@"log.txt", data);
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
然后:
[Log]
public ActionResult Index()
{
return View();
}
Run Code Online (Sandbox Code Playgroud)
但是,我建议您使用.NET框架内置的跟踪功能,而不是重新发明轮子.
归档时间: |
|
查看次数: |
1737 次 |
最近记录: |