|
I create multiple STA threads and start them. Once I have started all the threads in my main thread I need to wait till all of them are done.
To wait I tried
WaitHandle.WaitAll() ----- returns exception
Tried
waitEvent.waitOne()
and thread.Join()
In above case some times my main thread slips through Join\waitOne(). (i.e. main thread does not wait till all other threads are done)
Please advice how to implement this?
My sample code is as below
Main()
{
...
...
ArrayList myThreadClass = new ArrayList(3);
ArrayList threads = new ArrayList(3);
for(int i = 0 ; i< 3;i++)
{
ThreadClass thClass = new ThreadClass();
myThreadClass.Add(thClass);
Thread myThread = new Thread( new ThreadStart(thClass.threadMethod));
myThread.ApartmentState = ApartmentState.STA;
threads.Add(myThread);
((Thread)threads[i]).Start();
}
for(int k = 0;k<3;k++)
{
((Thread)threads[k]).Join();
}
.....
.....
} //Main Ends
Some more info
In my thread method I do some COM calls and make some callls Writeline to StreamWriter
Sandeep Naik
|
|
|
|
|
Hello
You can go through your threads using a loop and check the IsAlive property of each
bool Finished = false;
while(!Finished)
{
Finished = true;
foreach(Thread T in Threads)
{
if(T.IsAlive)
Finished = false;
}
Thread.Sleep(100)
}
Otherwise you can check the ThreadState property
Regards
|
|
|
|
|
Will I be blocking message pump here ?
Sandeep Naik
|
|
|
|
|
I tried something like this and it works with some of my testing ..
Do you think if this correct ? or will there be any issues with this
for(int temp = 0; temp <threadcount;temp++)
{
thread mythread="(Thread)GRDumpThread[temp];
if(myThread.IsAlive)
{
waitEvents[temp].WaitOne();
}
}"
<div="" class="ForumSig">Sandeep Naik
|
|
|
|
|
Hello
Your code segments are inconsistent and somehow don't add up!! For example what is GRDumpThread??
Anyway, if you want to use WaitHandle class, you should register your threads in ther ThreadPool queue. Take a look at this example taken from MSDN:
using System;
using System.Threading;
public sealed class App
{
static WaitHandle[] waitHandles = new WaitHandle[]
{
new AutoResetEvent(false),
new AutoResetEvent(false)
};
static Random r = new Random();
static void Main()
{
DateTime dt = DateTime.Now;
Console.WriteLine("Main thread is waiting for BOTH tasks to complete.");
ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[0]);
ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[1]);
WaitHandle.WaitAll(waitHandles);
Console.WriteLine("Both tasks are completed (time waited={0})",
(DateTime.Now - dt).TotalMilliseconds);
dt = DateTime.Now;
Console.WriteLine();
Console.WriteLine("The main thread is waiting for either task to complete.");
ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[0]);
ThreadPool.QueueUserWorkItem(new WaitCallback(DoTask), waitHandles[1]);
int index = WaitHandle.WaitAny(waitHandles);
Console.WriteLine("Task {0} finished first (time waited={1}).",
index + 1, (DateTime.Now - dt).TotalMilliseconds);
}
static void DoTask(Object state)
{
AutoResetEvent are = (AutoResetEvent) state;
int time = 1000 * r.Next(2, 10);
Console.WriteLine("Performing a task for {0} milliseconds.", time);
Thread.Sleep(time);
are.Set();
}
}
Whatever you use, just make it work.
And for the method I posted earlier, yes it blocks your message pump.
Regards
|
|
|
|
|
Thanks for all your help... It was very use full
Sandeep Naik
|
|
|
|
|
Hello,
does anyone know how to make a true copy of the reference object to the new variable as if it was a value type?
An object is passed to my DLL from the application and I need to compare the object's contents between the calls.
Thanks much,
Michal
|
|
|
|
|
Hello
This epends on what type of reference object you are talking about. Each class implements a "Cloning" method accordingly. Some well known way of copying reference types -if available- are:
1- All classes derived from System.Object inherit a protected method called MemberwiseClone() . Remember this is protected, so you could use it if you inherit from that class only.
2- Some reference types override the = operator to perform copying of data rather than references. Known example is the System.String class.
3- Other types include a copy constructor where you could construct an object from the values of another.
Again if all the above is not available in your reference type, then you'll just have to make your own way of copying public members.
Regards
|
|
|
|
|
Hello,
thanks. Unfortunately, the object passed to my DLL doesn't implement any of the cloning methods so I will need to compare the object properties by storing them and comparing them one by one.
Thanks.
Michal
|
|
|
|
|
At the moment I have the following classes :
Record ( which is the superclass )
- MessageHeaderRecord ( the superclass for the next classes ) :
- InfosRecord ( the class for the I tag
representing the informations from text )
- CommentRecord
- OrderRecord
- ResultsRecord
- TerminatorRecord
For each of this classes I have a corresponding class (MessageHeaderRecordFields ,...) in which I created the fields to put the infos from the file.
So far so good ...
MessageHeaderRecord beeing the superclass for the rest of classes I put inside of it a generic List :
private List m_Infos = new List()
internal List Infos
{
get
{
return m_Infos;
}
}
and the constructor is
internal MessageHeaderRecord()
{
RecordType = RecordType.MessageHeaderRecord;
m_Fields = new MessageHeaderRecordFields(); //
}
I did this because I want to access the objects as follows :
Message MyMessage = new Message();
MyMessage.Infos[3].Fields.SequenceNumber = "1";
MyMessage.Infos[3].Fields.InfoName.LastName = "John";
// Create a new info
int nInfoIndex = MyMessage.AddNewInformation(); (*1)
// Set the info specific data such as name, age, etc. for the info we just addded
MyMessage.Infos[nInfoIndex].Fields.InfoName.LastName = "John";
// Add an order record for this patient
int nOrderIndex = MyMessage.Infos[nInfoIndex].AddNewOrder(); (*2)
// Set the order specific information for the new order
MyMessage.Infos[nInfoIndex].Orders[nOrderIndex].Fields.OrderID = "11";
// Add a comment to this order
MyMessage.Infos[nInfoIndex].Orders[nOrderIndex].AddNewComment(); (*3)
// Set the text for the new comment
MyMessage.Infos[nInfoIndex].Orders [nOrderIndex].Commment.Fields.CommentText = "I am a comment.";
// Add a Result to this order
nResultIndex = MyMessage.Infos[nInfoIndex].Orders[nOrderIndex].AddNewResult();
// Set the new result's data
MyMessage.Infos[nPatientIndex].Orders[nOrderIndex].Results[nResultIndex].Fields.SequenceNumber = "333"; (*4)
So my problems redefined would be
(*1) - In which class to put the AddNewInformation() method
(*2) - In which class to put the Orders List and where to put the AddNewOrder() method
(*3) - In which class to put the Comment List and where to put the AddNewComment() method
(*4) - Same with Results List and AddNewResults() method
Please help me with this issues because I really cant figure them out.
Thank you in advance
|
|
|
|
|
Maybe I'm getting this wrong, but from what I understood, all the Add* methods are a bit reduntant if you don't do any special initialization inside them. For example in *1:
<br />
int nInfoIndex = MyMessage.AddNewInformation(); (*1)<br />
MyMessage.Infos[nInfoIndex].Fields.InfoName.LastName = "John";<br />
Could just be done like:
<br />
Info information = new Info (firstName, lastName, ...);<br />
MyMessage.Infos.Add (Info);<br />
While this doesn't retrieve the index so you can change afterwards, you can setup the class beforehand and then add it.
This can be used for all the other questions as far I understand.
If this wasn't what you were asking, then my apoligies.
Bruno Sousa
Software Consultant
http://www.luasys.com
|
|
|
|
|
Hey, simple question really.. i guess it could be done either way but i'm just wondering what the BEST way to do this is.
Basically the problem is very simple. all i want to do is pass a string from one application to another... just one direction. I'm wondering what the quickest and best way to go about this is. Should i just open up a TCP connection using windows sockets and pass it that way or should i try using remoting?
I'm sure the solution is simple but i don't want to do anything overkill just to pass a string
Thanks!
|
|
|
|
|
Socket. Anything else would be overkill in your case.
Best,
Jun
|
|
|
|
|
a web service would take about 3 minutes to create and publish
--------------------------------------------------------
1 line of code equals many bugs. So don't write any!!
My mad coder blog
|
|
|
|
|
I have a Blob field in a table in oracle database. Some times i need
to put null values into this field
This is what iam doing in my C# Code
byte[] blobTest = new byte[0];
string insert = "INSERT INTO exampel VALUES(:test)";
OracleParameter test = new OracleParameter();
test.OracleType = OracleType.Blob;
test.ParameterName = "test";
test.Value = blobTest;
con.Open();
cmd = new OracleCommand(insert, con);
cmd.Parameters.Add(test);
cmd.ExecuteNonQuery();
cmd.Dispose();
con.Close();
Its throwing up an error ORA-01459 invalid length for variable
if i change
byte[] blobTest = new byte[1]; in the above code its working.
Basically how do i pass in a null value for a blob field in oracle database.
Thanks
kal
|
|
|
|
|
Could you please replace these lines below
<br />
test.OracleType = OracleType.Blob;<br />
test.ParameterName = "test";<br />
test.Value = blobTest;<br />
with these lines
<br />
test.OracleType = OracleType.Blob;<br />
test.IsNullable = true;<br />
test.ParameterName = "test";<br />
test.Value = null;<br />
i haven't done anything in oracle yet but it sounds related to your problem ;D
and instead of setting the value to a bytearray consisting of one byte,
you should try to put a c# null value on it because the developers probably
implemented a c# null to oracle null conversion ;D
|
|
|
|
|
Hi, I develop an ERP from my company and now I've got a strange error:
"Assembly.createInstance contructor not found"
the error occurs in the code below:
<br />
Assembly asmForm;<br />
asmForm = Assembly.LoadFrom(MyLib.dll);
<br />
myOther Other = new myOther();<br />
<br />
Other.Name = "Walter";<br />
<br />
Form obj; <br />
obj = (Form)asmForm.CreateInstance("cForms.frmClass",<br />
true,<br />
BindingFlags.Public | BindingFlags.CreateInstance,<br />
null,<br />
new object[] { (Other) },<br />
System.Globalization.CultureInfo.CurrentCulture,<br />
null);<br />
<br />
((Form)obj).Show();<br />
Form will be load Dynamic
<br />
namespace cForms<br />
{<br />
public partial class frmClass : Form <br />
{<br />
<br />
public frmLista(myOther Other)<br />
{<br />
} <br />
Other Class
<br />
namespace cForms<br />
{<br />
public class myOther<br />
{<br />
public string Name;<br />
}<br />
}<br /> e;
}
}
-- modified at 14:09 Wednesday 30th August, 2006 e;
}
}
|
|
|
|
|
Hello,
I think you just have to add a default constructor to your class.
Walter O Dias wrote: I've got a strange error:
"Assembly.createInstance contructor not found"
Hope that means "constructor".
If yes, you just add.
namespace cForms<br />
{<br />
public partial class frmClass : Form <br />
{<br />
<br />
public frmClass()<br />
{<br />
}<br />
<br />
public frmLista(myOther Other)<br />
{<br />
}
Hope thats it!
All the best,
Martin
|
|
|
|
|
I put but, same error occurs.
Now I try to use Generics (Activator.CreateInstance<>) work fine, but i not have the implementation with parameters!
|
|
|
|
|
Hey,
I have a hashtable containing 100 images. When I try to serialize this down a network stream I get a 'Internal GDI+ error". The code looks something like this:
<br />
BinaryFormatter bf = new BinaryFormatter();<br />
bf.serialize(_Stream,_Images);<br />
Any ideas?
Many Thanks
Tom
|
|
|
|
|
Hi ALl,
I have developed a control library, and am running into some problems with serialization. When trying to serialize one of my controls, the serializer complains when it runs into something like the following:
[Serializable]
public class Control
{
public ContextMenu {get{...} set{...}}
}
So, the ContextMenu class is not serializable. If I try something like this:
[Serializable]
public class Control
{
[NonSerialized]
public ContextMenu {get{...} set{...}}
}
I will get another error that the NonSerialized attribute is only for fields or something. Apparently this only works for simple types, ie int's, strings? Is there another attribute to tell it to ignore a certain property when serializing?
Thanks in advance
|
|
|
|
|
Hi all,
First of all, please look at the following image:
http://img171.imageshack.us/img171/6038/graphne9.jpg[^]
I'm currently working on a reporting system for our web stats system.
Code:
Pen Black = new Pen(Brushes.Black, 1);<br />
Pen Gray = new Pen(Brushes.LightGray, 1);<br />
Bitmap b = new Bitmap(parentWidth,parentHeight);<br />
Graphics g = Graphics.FromImage(b);<br />
<br />
g = GenerateBG(g, parentWidth, parentHeight);
<br />
int width = parentWidth - 50;
int height = parentHeight - 50;
<br />
int spacer_width = width/7;
int spacer_height = 0;<br />
<br />
int maxCount = 0;<br />
<br />
ArrayList Data = new ArrayList();<br />
<br />
<br />
<br />
for(int i = -6; i < 1; i++)<br />
{<br />
DateTime date = DateTime.Now.AddDays(i);<br />
string toWrite = date.Day.ToString() + "/" + date.Month.ToString();<br />
g.DrawString(toWrite, new Font("Verdana", 7), Brushes.Black, ((i+7)*spacer_width), parentHeight -20);<br />
object[] dateData = dal.getStatsForDate(date.Date);<br />
if(dateData.Length > maxCount)<br />
maxCount = dateData.Length;<br />
Data.Add(dateData);<br />
}<br />
<br />
spacer_height = (height/maxCount);
<br />
int tempHeight = parentHeight;
<br />
int modCheck = Isqrt(maxCount);
<br />
for(int i = 0; i < maxCount; i++)<br />
{<br />
if((i%modCheck)==0)
{<br />
g.DrawLine(Gray, 50, tempHeight-25, width+25, tempHeight-25);
g.DrawString(i.ToString(),new Font("Verdana", 7), Brushes.Black, 5, tempHeight-32);
}<br />
tempHeight = (tempHeight-spacer_height);
}<br />
<br />
g.DrawLine(Black, 50, 25, 50, parentHeight-25);
g.DrawLine(Black, 50, parentHeight - 25, parentWidth-25, parentHeight-25);
Now if you look at the image and the code, i've got something wrong and I can't figure where.
Basically, I have calculated the distance between each number/guide line by deviding the height by the maximum number which will be shown.
For some strange reason, it is not using the whole height of the grid.
Anyone have any idea why?
|
|
|
|
|
could you check the maxCount variable for its value? it seems like its value is too big.. like 2 times bigger than it should be...
On the other hand i don't know the value of ParentHeight so it could be possible that you're calculating with a wrong value all the time...
what exactly is that "dal" object you're using? What exactly does the getStatsForDate method and are you sure its outpu is correct?
|
|
|
|
|
maxCount will currently read 90.
parentHeight = 200
parentWidth = 700
dal is my data access layer, and getStatsForDate will take a date, and get all records in the database against this date.
maxCount will start off life as zero, and each time I loop through the dates, and retrieve the
data via getStatsForDate, I check the length to see how many rows were returned. If the amount of rows returned is more then the current value of maxCount, maxCount will change to the amount of rows.
Thanks for replying.
|
|
|
|
|
I think I may have sorted it.
rather then using the maxCount to calculate the space between lines etc, I have got the square root of the maxCount and devided that by the height.
Regardless of the maxCount value, it seems to be sticking in the correct place.
Thanks
|
|
|
|