小应用程序中的线程同步

发布于 2024-10-22 13:19:33 字数 3501 浏览 1 评论 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();
}

您能否向我展示如何同步它,以使多个线程同时访问日志文件(当它们想要保存某些内容时)?我听说这是典型的生产者-消费者问题,但我不知道如何在我的案例中使用它。如果有任何停顿,我将非常感激。问候。

I have the following problem. I finishing my application, which one do something. Simultaneously some code (drwaing charts and save data to log file) can be using by a few threads. I can't synchornize save data which those threads. There is some exception that file is using by other process. On form1.cs file I'm starting this threads, which are starting function on another file (charts.cs).

Part of form1.cs file:

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

charts.cs file:

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)
        {

        }
    }         
}

}

Part of userControl1.cs file:

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

Can you show me how to synchronize it to happen that a few threads have accessed in the same time to a log file (when they want to save something)? I heard that this is typical producer-consumer problem but I d'nt know how to use it in my case. I will be very greatefull for any halp. Regards.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

空心↖ 2024-10-29 13:19:33

您可以使用 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);

You can use the lock() function of C# to lock an object which will allow you to only allow one thread at a time inside the lock() function.

1) Create an object to use as a lock in your class.

static readonly object LogLock = new object();

2) Move your logging code into it's own method and use the lock() function to force only one thread at a time to execute the critical area, in this case the StreamWriter stuff.

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

3) Call your threadsafe logging method concurrently with as many threads as you want.

WriteLog("test log text.", sw);
初懵 2024-10-29 13:19:33

take a look at the Semaphore class. You can use it to synchronize threads accessing the file. In short, you want to have only one thread write to the file at any given point in time.

软糖 2024-10-29 13:19:33

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

You can create additional method for writing log.
Then you can synchronize this method.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文