Multithreading - writing to same file C#

M

mahendranepali

I am making a simulator application that will simulate different
concurrent users connecting to a database. the application creates
different userkeys and pushes them to the database tables. The business
procedures hence interpret the userkey as a seperate request and act
accordingly. For this I need to check the response time to the DB for
say thousands of concurrent users. So what I did created Threads in a
Loop and each thread invoked the DAL Class to query the DB. I just had
to log the response (time to return dataset) of the DAL methods and log
them to a text file.
this is a sample code for multithreads writing to the file.

public class yyy
{

private Mutex mut = new Mutex();

public static void Main()
{
Thread t;
for(int i=1;i<=3;i++)
{
t = new Thread(new ThreadStart(new zzz().abc));
t.Start();
t.Join();

}

}
public void abc()
{
//Calls to DAL methods

this.WriteToFile();
}
private void WriteToFile()
{
mut.WaitOne();

using (StreamWriter sw = File.AppendText(@"d:\text.txt"))

try
{

sw.WriteLine(AppDomain.GetCurrentThreadId()) ;
sw.Flush();
sw.Close();
}
catch (Exception e)
{
Console.WriteLine("error:{0}", e);
}

finally
{
mut.ReleaseMutex();
}



}
}

The issue is that I have to use the Thread.Join() method else the main
terminates. Hence not all threads execute. But if I use Thread.Join()
then there are no concurrent users connecting. can anyone help me with
this.

Regards
Mickey
 
S

shiv_koirala

Thread.Join blocks a thread until a thread completes.So definetly you
will not have a simultaneous execution....Have you tried thread.sleep
but call it after the main for loop.

Just guessing......

C#, VB.NET , SQL SERVER , UML , DESIGN Patterns Interview question book
http://www.geocities.com/dotnetinterviews/
 
M

Mickey

hi,
i did tried using Thread.Sleep(10000) outside the main loop. Doesn't
work. Only one thread writes to the file.
 
L

Leon Lambert

Here is a very simple way that is use to preven main from leaving.
System.Console.Out.WriteLine("Hit return to exit");
System.Console.In.ReadLine();
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

Use Lambert's sugestion to avoid the main thread to end,
Also I would change your code,

public class yyy
{

private object o = new object();
StreamWriter sw = File.AppendText(@"d:\text.txt") ;

public static void Main()
{
Thread t;
for(int i=1;i<=3;i++)
{
t = new Thread(new ThreadStart(new zzz().abc));
t.Start();

}
Console.ReadLine() ;
}

public void abc()
{
//Calls to DAL methods

lock(o)
{
sw.WriteLine( .... );
}
}


cheers,
 
M

Mickey

Thanks Ignacio,Leon
It worked. Thanks for all your help. Here's is my final code for anyones
else reference

public class yyy
{

private object o = new object();
private Mutex mut = new Mutex();

public static void Main()
{
Thread t;
for(int i=1;i<=3;i++)
{
t = new Thread(new ThreadStart(new yyy().abc));
t.Start();

}
System.Console.Out.WriteLine("Hit return to exit");
System.Console.In.ReadLine();

}
public void abc()
{
//Calls to DAL methods

this.WriteToFile();
}
private void WriteToFile()
{
mut.WaitOne();

lock(o)
{
StreamWriter sw = File.AppendText(@"d:\text.txt");

try
{

sw.WriteLine(AppDomain.GetCurrentThreadId()) ;
sw.Flush();
sw.Close();
}
catch (Exception e)
{
Console.WriteLine("error:{0}", e);
}



}
mut.ReleaseMutex();

}
}
 
J

Jon Skeet [C# MVP]

Mickey said:
It worked. Thanks for all your help. Here's is my final code for anyones
else reference

Why do you have a mutex *and* a lock? Why not just use the lock?##
 
I

Ignacio Machin \( .NET/ C# MVP \)

Hi,

In addition to what Jon said I would advise you to not open/close the file
on each operation, open it in the main thread and let it open, it would
improve your performance

cheers,
 
Joined
Sep 16, 2005
Messages
1
Reaction score
0
Same issue

I am running into a similar issue. I am trying to access the database through DAL and waiting on a reply from the object... I want to capture the amount of time it takes to retrieve the information. I am using NUnit to get this done.

I have attached the whole code here.... can someone help me out with how I can captures all the results to the file... I usually am able to capture only 4-10 results when I try to open more than 20 threads...

My problem is identical to the above described problem.

namespace UnitLoadTests.TrackingLocal
{
[TestFixture]
[Category("Non-generated")]
public class TrackingScreen_Load_Test : UnitLoadTestBase
{
#region Constructor
public TrackingScreen_Load_Test()
{
myLoadTest = new UnitLoadTestHelper();
}

#endregion

#region Setup and TearDown
[SetUp]
protected void RunBeforeAllTests()
{

}
[TearDown]
public void CleanUp()
{

}
#endregion

#region Private Variables & Methods
private UnitLoadTestHelper myLoadTest;
private static Guid publicView = new Guid("C34125A7-FEB8-41F5-8C7F-F014FCBB5FAE");
private static Guid privateView = new Guid("EF152C17-6D5A-45FB-8BA0-DAE758C4AD20");
private static Guid allView = new Guid("EFC9B55F-7946-40BC-B3CE-6FC67F14BACF");
private static string path = "C:\\LoadTest_" + DateTime.Now.ToString("yyyyMMddhhmmss") + ".csv";
private object o = new object();
private static Mutex mut = new Mutex();

public void WriteLog (string LogEntry)
{

mut.WaitOne(1000,true);

lock(o)
{
StreamWriter sw = File.AppendText(@path);

try
{

sw.WriteLine(@LogEntry) ;
sw.Flush();
sw.Close();
}
catch (Exception e)
{
Console.WriteLine("error:{0}", e);
}
}
mut.ReleaseMutex();

}

private void RunTestThread(int PullCount)
{
//Fire off all the threads to create a load
Thread[] InstanceCaller = new Thread[PullCount];
for(int i=0; i < PullCount; i++)
{
InstanceCaller = new Thread(new ThreadStart(this.QueryTrackingScreenLocal));
InstanceCaller.Name = (i+1).ToString();
InstanceCaller.Start();
Thread.Sleep(500);
}
bool loopCont = true;
//Wait for all the threads to exit...
while(loopCont)
{
for(int i=0; i < PullCount; i++)
{
if (InstanceCaller.IsAlive)
{
loopCont = true;
break;
}
else
{
loopCont = false;
}
}
Thread.Sleep(1000);
}
//Test Completed

}


private void RunTestLinear(int PullCount)
{
for(int i=0; i < PullCount; i++)
{
QueryTrackingScreenLocal();
Thread.Sleep(500);
}
}


private void QueryTrackingScreenLocal()
{
//ACCESS THE DAL LAYER...
reply = //FROM MSMQ... PAYLOAD
try
{
DataSet dsRet = null;
if(reply.Error != null)
{
WriteLog(Thread.CurrentThread.Name + ",-1," + DateTime.Now.ToString("hh:mm:ss") + ",The payload threw an Error: " + reply.Error.Message
+ "---The source of the Error: " + reply.Error.Source
+ "---The stack trace of the Error: " + reply.Error.StackTrace);
}
else
{
dsRet = (DataSet)reply.TryPayload();
WriteLog(Thread.CurrentThread.Name + "," + dsRet.Tables[0].Rows.Count + "," + DateTime.Now.ToString("hh:mm:ss"));
}
}
catch (Exception ex)
{
WriteLog(",,The payload threw an exception " + ex.Message + "\n" + ex.Source + " >>> " + ex.StackTrace);
}

}

#endregion

#region Test Cases
[Test]
public void a_Pull_Tracking_Screen_DataSet_1Sec_10_Local_Linear()
{
WriteLog("Running Test of pulling tracking screen through LocalProxy 10-1 (Liner Mode),0," + DateTime.Now.ToString("hh:mm:ss"));
RunTestLinear(10);
WriteLog("End-time,0," + DateTime.Now.ToString("hh:mm:ss"));

}


[Test]
public void b_Pull_Tracking_Screen_DataSet_1Sec_20_Local_Linear()
{
WriteLog("Running Test of pulling tracking screen through LocalProxy 20-1 (Liner Mode),0," + DateTime.Now.ToString("hh:mm:ss"));
RunTestLinear(20);
WriteLog("End-time,0," + DateTime.Now.ToString("hh:mm:ss"));
}

[Test]
public void c_Pull_Tracking_Screen_DataSet_1Sec_50_Local_Linear()
{
WriteLog("Running Test of pulling tracking screen through LocalProxy 50-1 (Liner Mode),0," + DateTime.Now.ToString("hh:mm:ss"));
RunTestLinear(50);
WriteLog("End-time,0," + DateTime.Now.ToString("hh:mm:ss"));
}


[Test]
public void d_Pull_Tracking_Screen_DataSet_1Sec_100_Local_Linear()
{
WriteLog("Running Test of pulling tracking screen through LocalProxy 100-1 (Liner Mode),0," + DateTime.Now.ToString("hh:mm:ss"));
RunTestLinear(100);
WriteLog("End-time,0," + DateTime.Now.ToString("hh:mm:ss"));
}

[Test]
public void e_Pull_Tracking_Screen_DataSet_1Sec_10_Local_Thread()
{
WriteLog("Running Test of pulling tracking screen through LocalProxy 10-1 (Thread Mode),0," + DateTime.Now.ToString("hh:mm:ss"));
RunTestThread(10);
WriteLog("End-time,0," + DateTime.Now.ToString("hh:mm:ss"));
}


[Test]
public void f_Pull_Tracking_Screen_DataSet_1Sec_20_Local_Thread()
{
WriteLog("Running Test of pulling tracking screen through LocalProxy 20-1 (Thread Mode),0," + DateTime.Now.ToString("hh:mm:ss"));
RunTestThread(20);
WriteLog("End-time,0," + DateTime.Now.ToString("hh:mm:ss"));
}

[Test]
public void g_Pull_Tracking_Screen_DataSet_1Sec_50_Local_Thread()
{
WriteLog("Running Test of pulling tracking screen through LocalProxy 50-1 (Thread Mode),0," + DateTime.Now.ToString("hh:mm:ss"));
RunTestThread(50);
WriteLog("End-time,0," + DateTime.Now.ToString("hh:mm:ss"));
}


[Test]
public void h_Pull_Tracking_Screen_DataSet_1Sec_100_Local_Thread()
{
WriteLog("Running Test of pulling tracking screen through LocalProxy 100-1 (Thread Mode),0," + DateTime.Now.ToString("hh:mm:ss"));
RunTestThread(100);
WriteLog("End-time,0," + DateTime.Now.ToString("hh:mm:ss"));
}


#endregion
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top