我有以下问题。我完成了我的应用程序,哪一个做了什么。同时,一些代码(drwaing chart并将数据保存到日志文件)可以由几个线程使用。我无法同步保存那些线程的数据。其他进程正在使用该文件。在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();
}
你能告诉我如何将它同步到一些线程同时访问日志文件(当他们想要保存某些东西时)吗?我听说这是典型的生产者 - 消费者问题,但我知道如何在我的案例中使用它。任何挫折都会让我非常满意。问候。
答案 0 :(得分:1)
您可以使用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);
答案 1 :(得分:0)
您可以创建其他写日志的方法。 然后你可以同步这个方法。
答案 2 :(得分:0)
看一下Semaphore
课程。您可以使用它来同步访问该文件的线程。简而言之,您希望在任何给定的时间点只有一个线程写入文件。