2017-02-02 5 views
5

После много исследований, и после прочтения и рассмотрения всех вопросов здесь, я думаю, пришло время попросить о помощи.Многопоточность блокировки чтения/записи текста C#

У меня есть приложение на C#, и я пытаюсь записать в SAME файл с другим потоком.

public static void LaunchThreads(string path_file) 
{ 
    int i = 0; 
    Dictionary<int, Thread> threadsdico = new Dictionary<int, Thread>(); 
    while (i < MAX_THREAD) 
    { 
      Thread thread = new Thread(() => ThreadEntryWriter(string path_file)); 
      thread.Name = string.Format("ThreadsWriters{0}", i); 
      threadsdico.Add(i, thread); 
      thread.Start(); 
      i++; 
    } 
    int zz = 0; 
    while (zz < threadsdico.Count()) 
    { 
     threadsdico[zz].Join(); 
     zz++; 
    } 
} 
private static readonly Object obj = new Object(); 
public static void ThreadEntryWriter(string path_file) 
{ 
    int w = 0; 
    while (w < 99) 
    {  
     string newline = w + " - test" + "\r"; 
     lock(obj) 
     { 
      string txt = File.ReadAllText(path_file); 
      using (TextWriter myWriter = new StreamWriter(path_file)) 
      { 
       TextWriter.Synchronized(myWriter).Write(txt + newline); 
      } 
     } 
     w++; 
    } 
} 

Я все попробовать, мой код глобально так, но я стараюсь всячески, с каждым замком, каждый файл открытым способом, но я получаю The process cannot access the files because it's in use. Строкой, которая генерирует эту ошибку, является этот using (TextWriter myWriter = new StreamWriter(path_file)).

Я пробовал много вещей, закрывая файлы и т. Д., Но когда потоки начинают работать в одно и то же время, программа останавливается и дает мне ошибку The process cannot access the files because it's in use (самообучаться). Но я не понимаю, почему блокировка предполагает блокировать другой поток, чтобы войти сюда. И я использовал метод Synchronized для записи, который является потокобезопасным. Ну, извините за длинное письмо, это мой первый пост здесь.

+0

«программа остановится и дайте мне ошибку». - можете ли вы поделиться своей ошибкой? –

+2

Уверены ли вы, что нет другого кода, который откроет файл? Если да - выключите антивирусные сканеры и повторите попытку. –

+0

Ошибка - это что-то вроде «Процесс не может получить доступ к файлам, потому что он используется». – tucotraff

ответ

0

Синхронное писатель все еще должны быть расположены:

var newline = w + " - test"; 
using (var sw = new StreamWriter(path_file)) 
using (var sync = TextWriter.Synchronized(sw)) 
{ 
    // no need to add a new line char, just use other method to write 
    sync.WriteLine(txt + newline); 
} 

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

0

Я тестирую ваш код и применяю некоторые изменения, и он отлично работает без ошибок.

Я использовал приложение winform для запуска вашего кода. Пожалуйста, проверьте код ниже.

using System; 
using System.Collections.Generic; 
using System.ComponentModel; 
using System.Data; 
using System.Drawing; 
using System.IO; 
using System.Linq; 
using System.Text; 
using System.Threading; 
using System.Threading.Tasks; 
using System.Windows.Forms; 

namespace WindowsFormsApplication14 
{ 
    public partial class Form1 : Form 
    { 
     private readonly Object obj = new Object(); 

     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void Form1_Load(object sender, EventArgs e) 
     { 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      LaunchThreads("D:\\log.txt"); 
     } 

     public void LaunchThreads(string path_file) 
     { 
      int i = 0; 
      int MAX_THREAD = 10; 
      Dictionary<int, Thread> threadsdico = new Dictionary<int, Thread>(); 
      while (i < MAX_THREAD) 
      { 
       Thread thread = new Thread(() => ThreadEntryWriter(path_file, string.Format("ThreadsWriters{0}", i))); 
        thread.Name = string.Format("ThreadsWriters{0}", i); 
        threadsdico.Add(i, thread); 
        thread.Start(); 
        i++; 
      } 
      int zz = 0; 
      while (zz < threadsdico.Count()) 
      { 
       threadsdico[zz].Join(); 
       zz++; 
      } 
     } 

     public void ThreadEntryWriter(string path_file,string threadName) 
     { 
      int w = 0; 
      while (w < 99) 
      { 
       string newline = w + " - test" + " Thread:" + threadName + "\r\n"; 
       lock (obj) 
       { 
        string txt = File.ReadAllText(path_file); 
        using (TextWriter myWriter = new StreamWriter(path_file)) 
        { 
         TextWriter.Synchronized(myWriter).Write(txt + newline); 
        } 
       } 
       w++; 
      } 
     } 
    } 
} 

Я получил выход, как показано ниже.

  • 0 - Тест Тема: ThreadsWriters1
  • 0 - Тест Тема: ThreadsWriters2
  • 1 - Тест Тема: ThreadsWriters2
  • 2 - Тест Тема: ThreadsWriters2
  • 1 - Тест Тема: ThreadsWriters1
  • ....
  • ....