threads synchronisation in little application
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.
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);
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.
You can create additional method for writing log. Then you can synchronize this method.
精彩评论