2012-04-19 3 views
1

Я хочу асинхронной журнал записи в ASP.NET MVC, код выглядит так:использование журнала асинхронной записи в 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); 
     } 

Но результат я не ожидал, некоторых журналов не быть зарегистрированным, может кто-нибудь сказать мне, что не так с кодом

ответ

6

Вам нужно убедиться, что в файл записывается только один поток. Если у вас есть 2 одновременных пользователя, вызывающих действие индекса, в то же время есть вероятность, что они попытаются одновременно записать в файл журнала, а вторая не удастся. В многопоточных приложениях, таких как 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(); 
} 

и избежать такого шума и загрязнения окружающей среды в контроллерах вы можете использовать фильтры действия:

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); 
      } 
     }); 
    } 
} 

и затем:

[Log] 
public ActionResult Index() 
{ 
    return View(); 
} 

Но вместо того, чтобы изобретать колеса, я бы рекомендовал вам использовать tracing capabilities, встроенный в .NET framework.

+0

Благодарим вас за ответ, но в коде произошел сбой приложения: «Исключение (исключения) задачи не наблюдалось ни при ожидании задачи, ни при доступе к ее свойству Exception. В результате незаметное исключение было повторно указано в потоке финализатора «. – JeffZhnn

+0

Вы можете обернуть файл 'File.AppendAllText' в try/catch. Кажется, что в задаче есть исключение. Попробуйте отладить код, чтобы узнать, что это за исключением. –

Смежные вопросы