【问题标题】:threads synchronisation in little application小应用程序中的线程同步
【发布时间】:2011-07-16 00:32:24
【问题描述】:

我有以下问题。我完成了我的申请,哪一个做点什么。同时一些代码(绘制图表并将数据保存到日志文件)可以由几个线程使用。我无法同步保存这些线程的数据。文件被其他进程使用有一些例外。在 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();
}

你能告诉我如何将它同步到一个日志文件(当他们想要保存一些东西时)几个线程同时访问的情况吗?我听说这是典型的生产者-消费者问题,但我不知道如何在我的情况下使用它。对于任何暂停,我都会非常高兴。问候。

【问题讨论】:

  • 你不喜欢像“ZZZ”和“wpi”这样的变量名吗?

标签: c# multithreading asynchronous streamwriter


【解决方案1】:

您可以创建其他写入日志的方法。 然后就可以同步这个方法了。

【讨论】:

    【解决方案2】:

    看看Semaphore 类。您可以使用它来同步访问文件的线程。简而言之,您希望在任何给定时间点只有一个线程写入文件。

    【讨论】:

      【解决方案3】:

      您可以使用 C# 的 lock() 函数来锁定一个对象,这将允许您在 lock() 函数中一次只允许一个线程。

      1) 创建一个对象以用作类中的锁。

      static readonly object LogLock = new object();
      

      2) 将您的日志记录代码移动到它自己的方法中,并使用 lock() 函数强制一次只执行一个线程来执行关键区域,在本例中是 StreamWriter 的东西。

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

      3) 使用尽可能多的线程同时调用线程安全日志记录方法。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-02-06
        • 2018-12-17
        • 2012-10-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多