0

次の問題があります。私はアプリケーションを終了しました。どちらが何かをしますか。同時に、一部のコード (グラフの描画とログ ファイルへのデータの保存) がいくつかのスレッドで使用される可能性があります。それらのスレッドのセーブデータを同期できません。ファイルが他のプロセスによって使用されているいくつかの例外があります。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();
}

いくつかのスレッドが同時にログ ファイルにアクセスした場合 (何かを保存したい場合) に同期する方法を教えてもらえますか? これは典型的な生産者と消費者の問題だと聞きましたが、私の場合の使い方がわかりません。私はどんな半分でも非常に素晴らしいです。よろしく。

4

3 に答える 3

1

C# の lock() 関数を使用してオブジェクトをロックすると、lock() 関数内で一度に 1 つのスレッドのみを許可できます。

1) クラスでロックとして使用するオブジェクトを作成します。

static readonly object LogLock = new object();

2) ロギング コードを独自のメソッドに移動し、lock() 関数を使用して、一度に 1 つのスレッドのみが重要な領域 (この場合は StreamWriter のもの) を実行するように強制します。

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

3) 必要な数のスレッドと同時に、スレッドセーフ ロギング メソッドを呼び出します。

WriteLog("test log text.", sw);
于 2011-03-15T19:05:02.047 に答える
0

ログを書き込むための追加のメソッドを作成できます。次に、このメソッドを同期できます。

于 2011-03-15T18:16:16.003 に答える
0

Semaphoreクラスを見てください。これを使用して、ファイルにアクセスするスレッドを同期できます。つまり、任意の時点で1つのスレッドだけをファイルに書き込む必要があります。

于 2011-03-15T18:16:25.510 に答える