2017-02-02 62 views
5

Po wielu badaniach i po przeczytaniu i wypróbowaniu wszystkich pytań tutaj, myślę, że nadszedł czas, aby poprosić o pomoc.Wielowątkowa blokada odczytu/zapisu tekstu C#

Mam aplikację w języku C# i próbuję pisać w pliku SAME z innym wątkiem.

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

mam spróbować wszystkiego, mój kod jest globalnie tak, ale mam spróbować każdy sposób, z każdym zamkiem, każdej metody plików otwarte, ale wciąż otrzymuję The process cannot access the files because it's in use. Wiersz, który generuje ten błąd, jest ten using (TextWriter myWriter = new StreamWriter(path_file)).

Próbowałem wiele rzeczy, zamykając pliki itp., Ale gdy wątki zaczynają działać w tym samym czasie, program zatrzymuje się i daje mi błąd The process cannot access the files because it's in use (samouzupełnianie). Ale nie rozumiem, dlaczego zamek ma zablokować inny wątek, aby tu wejść. I użyłem metody zsynchronizowanej do napisania, która jest bezpieczna dla wątków. Bardzo przepraszam za długie pisanie, to mój pierwszy post tutaj.

+0

"zatrzymaj program i daj mi błąd." - czy możesz podzielić się swoim błędem? –

+2

Czy na pewno nie ma innego kodu, który otwiera plik? Jeśli tak, wyłącz skanery antywirusowe i spróbuj ponownie. –

+0

Błąd jest podobny do "Proces nie może uzyskać dostępu do plików, ponieważ jest w użyciu". – tucotraff

Odpowiedz

0

synchroniczne pisarz nadal należy wyrzucać:

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

Ponadto, można zapisać zmienną sync i nazywają to metody z wszystkich wątków i będzie wykonać całą pracę za ciebie, i można go wyrzucać później po napisaniu całego tekstu.

0

Testuję Twój kod i wprowadzam pewne zmiany, które działają bezbłędnie.

Do uruchomienia kodu użyłem aplikacji Winform. Sprawdź poniższy kod.

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

Mam dane wyjściowe jak poniżej.

  • 0 - test Wątek: ThreadsWriters1
  • 0 - test Wątek: ThreadsWriters2
  • 1 - test Wątek: ThreadsWriters2
  • 2 - test Wątek: ThreadsWriters2
  • 1 - test Wątek: ThreadsWriters1
  • ....
  • ....