2016-11-09 1 views
1

Я пытаюсь зарегистрировать каждый метод в своей программе, у меня есть приложение, развернутое на сервере IIS, и пользователь просто позвонил мне и сказал, что функциональность электронной почты не работает, поэтому мне нужно в основном запустить приложение, но запишите каждый шаг в txt-файл.Процесс не может получить доступ к файлу 'C: file.txt', потому что он используется другим процессом

Я объявляя ниже в качестве глобального значения:

StreamWriter writer = new StreamWriter("C:\\file.txt"); 

Затем я использую его, как показано ниже в моем коде:

Method 1 
{ 
    if (file1.HasFile) 
{ 
writer.WriteLine("Has File"); 
} 
} 

Способ 2

private Boolean InsertUpdateData(SqlCommand cmd) 
     { 
writer.WriteLine("Insert Started" + DateTime.Now.ToString()); 
} 

Так в моей case метод работает нормально, и он записывает файл, но когда он переходит во второй метод, я получаю, что файл уже открыт, что правильно, я могу обойти это?

Благодаря

Global Value - заявил на верхней

namespace WorkOrderManagement 
{ 
    public partial class CreateWorkOrder : System.Web.UI.Page 
    { 
     bool successfull; 
     string path; 
     string name; 
     string content; 
     string datas; 
     string ext; 
     bool affectedrows; 
     string seasonalsupervisor; 
     private string sLogFormat; 
     private string sErrorTime; 

     StreamWriter writer = new StreamWriter("C:\\file.txt"); 
+0

Что вы подразумеваете под "глобальной стоимостью"? Вы имеете в виду 'статический' член?Вы понимаете, что IIS многопоточен, а статические члены разделяются всеми запросами, не так ли? –

+0

Это немного запутывает код, который вы показываете, но, похоже, вам нужно освободить писателя, и вы этого не делаете. –

+0

«Как я могу обойти это?» Не используйте «глобальный» поток. Откройте файл, напишите ему, закройте его (желательно с помощью блока 'using'). –

ответ

2

Я действительно предлагаю вам отказаться от идеи иметь глобальную переменную для представления потока, а затем попытаться использовать ее разными способами. Это просто в настольном приложении, но намного сложнее в приложении ASP.NET.

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

Например, вы могли бы иметь метод, как этот

public static class Log 
{ 
    public static string _file = "log.txt"; 
    public static object _locked = new object(); 

    public static void AppendToLog(string text) 
    { 
     lock(_locked) 
     { 
      string path = Server.MapPath("~/APP_DATA"); 
      File.AppendAllText(Path.Combine(path, _file), text + Environment.NewLine); 
     } 
    } 
} 

Теперь вы можете вызвать запись журнала с

Log.AppendToLog("My message"); 

Я хочу подчеркнуть две важные вещи здесь. Сначала я не пишу в корневом диске сервера. Это плохая практика и всегда является источником проблем при развертывании приложения ASP.NET на сервере, где у вас нет прав на использование чего-либо вне вашего сайта. Таким образом, система ASP.NET определяет определенную папку под названием APP_DATA под вашим корнем сайта, где ваше приложение должно иметь права на чтение/запись. Второе замечание - использование ключевого слова lock. Это необходимо в среде, такой как ASP.NET, где два пользователя могут достичь точки кода, в которой вам нужно записать общий файл журнала. Как объясняет MSDN это

Ключевое слово замка гарантирует, что один поток не входит в критическую секцию кода, а другой поток находится в критической секции. Если другой поток пытается ввести заблокированный код, он будет ждать, блокировать, , пока объект не будет выпущен.

+0

Спасибо, что ты кодирующий ангел :) – CodeMan

0

Закрыть поток после записи файла

Method 1 
{ 
    if (file1.HasFile) 
{ 
writer.WriteLine("Has File"); 
writer.Close(); 
} 
} 
+0

ваш метод дает мне эту ошибку «Невозможно написать закрытому TextWriter». – CodeMan

+0

Поскольку StreamWriter.Close() необходимо снова открыть после закрытия, если вы хотите использовать его снова. Тогда вы должны сделать: 'writer = new StreamWriter (« C: \\ file.txt »);' в начале вашего второго метода. –

+0

Это не решает фундаментальной проблемы. Если два потока пытаются открыть и записать в файл, он будет испытывать ту же проблему. Должна быть какая-то явная синхронизация. –

1

вы также можете сделать это, чтобы закрыть поток файла

using (StreamWriter writer = new StreamWriter("C:\\file.txt")) 
{ 
    //your code here 
} 
//this automatically closes the stream, and it is more recommended. 
+0

Я не могу сделать это, потому что у меня есть другой метод в методе, который вставляет в базу данных, поэтому до того, как потоковик будет закрыт, он переходит в другой метод и говорит, что файл txt используется другим процессом. – CodeMan

+0

Это не решает фундаментальную проблему, которая заключается в том, что два потока одновременно пытаются получить доступ к одному и тому же файлу. Если оба попытаются написать одновременно, код не удастся. –

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

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