2011-03-15 26 views
0

我有以下問題。我正在完成我的應用程序,哪一個人在做什麼同時,一些代碼(drwaing圖表和保存數據到日誌文件)可以被幾個線程使用。我無法同步保存那些線程的數據。有一些例外,該文件正在使用其他進程。在form1.cs文件中,我將啓動這個線程,這是另一個文件(charts.cs)上的啓動函數。在小應用程序中的線程同步

Form1.cs的文件的部分:

UserControl1 us = ctrl as UserControl1; 
us.newThread = new Thread(new ThreadStart(us.wykres.CreateChart)); 
us.newThread.Start(); 

charts.cs文件:

public class Charts 
{ 
    private StreamWriter sw = new StreamWriter("logFile.txt", true); 

    static readonly object LogLock = new object(); 

    private ZedGraphControl zzz; 

    public ZedGraphControl ZZZ 
    { 
     get { return zzz; } 
     set { zzz = value; } 
    } 

    private UserControl1 uc1; 

    public UserControl1 Uc1 
    { 
     get { return uc1; } 
     set { uc1 = value; } 
    } 
    //jakiś kod 

    void WriteLog(string wpis, StreamWriter streamW) 
    { 
     lock (LogLock) 
     { 
      streamW.WriteLine(wpis); 
      streamW.Flush(); 
     } 
    } 

    public void CreateChart() 
    { 
     try 
     { 
      //tutaj znów jakiś kod 
      //poniżej najważniejsza 

       while() 
       { 

        if() 
        { 

         if (go == false) 
         { 
          ZZZ.Invoke(Uc1.warnDelegate, "Osiągnięto strefę bezpiecznych wartości"); 
         } 

         wpis = "jakis string"; 
         WriteLog(wpis, sw); 
         wpis = null; 
        } 
        if() 
        { 
         if() 
         { 
          ZZZ.Invoke(Uc1.warnDelegate, "Osiągnięto strefę 1"); 
         } 

         wpis = "jakis string"; 
         WriteLog(wpis, sw); 
         wpis = null; 
        } 
        else if() 
        { 
         if() 
         { 
          ZZZ.Invoke(Uc1.warnDelegate, "Osiągnięto strefę 2"); 
         } 

         wpis = "jakis string"; 
         WriteLog(wpis, sw); 
         wpis = null; 
        } 

       //jakiś kod odnośnie rysowania wykresow 

       ZZZ.Invoke(Uc1.myDelegate); 
       Thread.Sleep(odstepCzasu * 1000); 
       } 
     } 
     catch (InvalidOperationException e) 
     { 
      MessageBox.Show(e.Message); 
     } 
     catch (ThreadAbortException) 
     { 

     } 
    }   
} 

} userControl1.cs文件

部分:

public delegate void RefreshDelegate(); 
public delegate void ShowWarningDialogDelegate(string aaa, string bbb, string ccc);   
public RefreshDelegate myDelegate; 
public ShowWarningDialogDelegate warnDelegate; 
public Thread newThread = null; 

public Charts wykres = null; 

public UserControl1() 
{ 
    InitializeComponent(); 
    wykres = new Charts(); 
    wykres.ZZZ = zedGraphControl1; 
    wykres.Uc1 = this; 
    myDelegate = new RefreshDelegate(wykres.ZZZ.Refresh); 
    warnDelegate = new ShowWarningDialogDelegate(minDelegate); 
} 

private void minDelegate(string strLabel1, string strLabel2)   
{ 
    WarningForm forma = new WarningForm(strLabel1, strLabel2); 
    forma.Show(); 
} 

你可以嗎 告訴我如何進行同步,以便幾個線程同時訪問日誌文件(當他們想要保存某些內容時)?我聽說這是典型的生產者 - 消費者問題,但我不知道如何使用它。對於任何halp我都會非常感激。問候。

+0

難道你不喜歡像「ZZZ」和「wpi」這樣的變量名嗎....? – 2011-03-15 18:13:27

回答

0

您可以創建其他寫日誌的方法。 然後你可以同步這個方法。

0

請看Semaphore課。您可以使用它來同步訪問該文件的線程。簡而言之,您希望在任何給定的時間點只有一個線程寫入文件。

1

您可以使用C#的lock()函數來鎖定一個對象,該對象允許您一次只允許一個線程在lock()函數內。

1)創建一個對象用作班級中的鎖。

static readonly object LogLock = new object(); 

2)移動你的日誌代碼到它自己的方法,並使用鎖()函數來強制只有一個線程在同一時間執行關鍵區域,在這種情況下,StreamWriter的東西。

 void WriteLog(string wpis, StreamWriter sw) 
    { 
     lock (LogLock) 
     { 
      sw.WriteLine(wpis); 
      sw.Flush(); 
     } 
    } 

3)儘可能多線程,只要你想同時打電話給你的線程安全的測井方法。

WriteLog("test log text.", sw);