Will Keyword NEW reinitialize all others running function value in c#? - c#

I have a Class file to perform certain function , for example
public class clsFunction
{
public DataTable FunctionOne()
{
//some code
}
public void FunctionTwo()
{
//Some Code
}
}
SecondClass is use to call function from clsFunction , and this main class in running on a console program with multiple thread.
public class SecondClass
{
public void ThreadOne()
{
while(true){DataTable dt = new clsFunction().FunctionOne;}
}
public void ThreadTwo()
{
while(true){new clsFunction().FunctionTwo();}
}
}
class Main
{
static void Main (string[] args)
{
//Thread to start SecondClass.ThreadOne
//THread to start SecondClass.ThreadTwo
}
}
My concern is will my class value reinitialize to default value when I call new clsFunction() each time. for example , thread two may running it own value , when thread one is call , will all the thread two value change to it default value ?

Maybe you don't understand what new does. It creates an object. It's purpose is not to initialize something that already exists. Objects are independent.
Creating an object has no influence on any other object, except of course if the constructor does something to influence other objects.

Related

Calling a thread from another class (C#)

EDIT: Question answered. Answer explained perfectly by Igor. (Thank you!)
Question: How do I access/control a thread from another class in the same program?
I'm will be having multiple threads active (not all at once) and I need to check if one is active (that is not the main thread).
I am programming in C# and I am trying to use threading.
I have 2 classes, my thread starts in the main class calling a function in the other class. In my other class I want to see if "thread.isAlive == true" but I think it isn't publicly available. I don't know the syntax/code to be able to use the thread from another class? I'm struggling to get it working.
I can call the other class, but I can't call the thread between classes. (Can't declare a thread outside of a class)
The error thrown is:
Error 1 The name 'testThread' does not exist in the current context
Example code:
//Headers
using System.Threading;
using System.Threading.Tasks;
namespace testProgram
{
public class Form1 : Form
{
public void main()
{
//Create thread referencing other class
TestClass test = new TestClass();
Thread testThread = new Thread(test.runFunction)
//Start the thread
testThread.Start();
}//Main End
}//Form1 Class End
public class TestClass
{
public void runFunction()
{
//Check if the thread is active
//This is what I'm struggling with
if (testThread.isAlive == true)
{
//Do things
}//If End
}//runFunction End
}//testClass End
}//Namespace End
Thanks for reading!
-Dave
if (System.Threading.Thread.CurrentThread.isAlive == true) { ... }
But you are doing this: "Is the thread, in which I am executing, running? Yes it is running since the code that is doing the check is in it and I am currently in that code."
But if you insist:
public class Form1 : Form
{
public void main()
{
//Create thread referencing other class
TestClass test = new TestClass();
Thread testThread = new Thread(test.runFunction)
test.TestThread = testThread;
//Start the thread
testThread.Start();
}//Main End
}//Form1 Class End
public class TestClass
{
public Thread TestThread { get; set; }
public void runFunction()
{
//Check if the thread is active
if (TestThread != null && TestThread.isAlive == true)
{
//Do things
}//If End
}//runFunction End
}//testClass End

Thread using delegate or function name

Weird question.
What the difference using those piece of code?
class TestThread {
public void waitFunction() {
// Some code like this.UpdateProgress()
}
public void start() {
Thread thWaitingScraper = new Thread(waitFunction); // Method 1
Thread thWaitingScraper = new Thread(delegate() { waitFunction(); }); // Method 2
}
Thanks!
No functional difference, but a typeleak can be caused in the second method.
Typeleak is caused when the compiler needs to create an implicit class behind the scene. In this case, because twaitFunction is a non static member of the class, the compiler needs to create a class which holds the reference to this class so the function can be called with the appropriate instance. Within this class it creates the anonymous method you wrote in the second method and passes it as the Thread delegate parameter.

Null Exception accessing another class object

Forgive me, I'm learning C# and object-oriented programming. I am running two threads. Thread #2 calls a different class method. This method assigns an object's data value. Thread #1 unsuccessfully attempts to access the object's data value that Thread #2 assigned. The object's data value in Thread #1 is null. How do I access this object and all its assigned data values? I basically want to save the data variables from Thread #2 classes and access them from a Thread #1 class. It appears an object and it's data member values generated in a Thread #2 class are null when I leave the class and then try to access the same object in a Thread #1 class. Can I still save the instantiated object values in my example or should I declare things as static? Below is some of my code to illustrate my problem. Thank you for anyone that can recommend or illustrate how to resolve this.
// this is a main operating class that: 1) starts two threads and 2) trys to access the Thread #2 Lru_SetChanFreq class object data from Thread #1 Lru_operations class
public class Lru_operation
{
[STAThread]
static void Main()
{
// starts a separate thread #2
Lru_Listen LruListen1 = new Lru_Listen();
Thread LruListenThread = new Thread(new ThreadStart(LruListen1.ListenForAag));
LruListenThread.Start();
while(!LruListenThread.IsAlive)
;
Thread.Sleep(1);
// follows the main thread #1
Lru_operation LruOpX = new Lru_operation();
LruOpX.LruOperation();
}
// this is where main thread #1 operates
public void LruOperation()
{
// create object to access object data from thread #2 Lru_SetChanFreq class
Lru_SetChanFreq SetChFrq = new Lru_SetChanFreq();
try
{
// do stuff
// ERROR: SetChFrq.LruSetFrq.RxFreq2 = null and then catches an exception to go below.
// Why is this happening if Thread #2 previously sets RxFreq2 = 405.1?
Console.WriteLine("LruSetFrq.RxFreq2 = {0}", SetChFrq.LruSetFrq.RxFreq2);
// do more stuff
}
catch(Exception ex)
{
MessageBox.Show(ex.Message, "connection terminated",
MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
// this is called from thread #2. It's object is used by thread #1
public class Lru_SetChanFreq
{
#region fields
private string rxFreq2;
private Lru_SetChanFreq mLruSetFrq;
#endregion fields
#region Properties
public Lru_SetChanFreq LruSetFrq
{
get { return mLruSetFrq; }
set { mLruSetFrq = value; }
}
public string RxFreq2
{
get { return rxFreq2; }
set { rxFreq2 = value; Console.WriteLine("rxFreq2 = {0}", rxFreq2); }
}
#endregion Properties
#region methods
public Lru_SetChanFreq()
{
}
public void SetFreq()
{
mLruSetFrq = new Lru_SetChanFreq();
mLruSetFrq.RxFreq2 = "405.1";
// I confirmed that LruSetFrq.RxFreq2 = 405.1
Console.WriteLine("LruSetFrq.RxFreq2 = {0}", LruSetFrq.RxFreq2);
// do stuff
}
#endregion methods
}
// this is starting point of thread #2
public class Lru_Listen
{
#region Fields
// stuff
#endregion Fields
#region Properties
// stuff
#endregion Properties
#region Methods
public void ListenForAag()
{
// do stuff
LruListenAccReq();
}
public void LruListenAccReq()
{
// do stuff
LruShowRequestData(request);
}
public void LruShowRequestData(// stuff )
{
Lru_SetChanFreq SetChanFreq = new Lru_SetChanFreq();
SetChanFreq.SetFreq(); // calls to another class method
}
#endregion Methods
}
}
Your 2 Threads each make an instance of Lru_SetChanFreq . The 2 instances are not related or coupled. Setting a value on one thread (SetChanFreq.SetFreq()) has no bearing on the other thread.
A few points:
Try to pick meaningful, readable names. Prefixes like Lru_ have a negative impact on readability.
Study the meaning of object-instance (vs static) first. Leave threading alone until you have a good grasp of objects and memory management.
In the end you probably won't want to use Threads at all, ThreadPool and Task are more efficient and convenient.
Your issue is that you are initializing and accessing distinct Lru_SetChanFreq instances in your two threads. You should initialize just one, assign it to a class field, and then access the same instance from the other thread. Here is a trimmed-down version of your code that does that:
public class Lru_operation
{
[STAThread]
static void Main()
{
Lru_Listen LruListen1 = new Lru_Listen();
// Run LruListen1 on Thread 2
Thread LruListenThread = new Thread(new ThreadStart(LruListen1.ListenForAag));
LruListenThread.Start();
// Wait for its operation to complete
// There is no need to wait for the thread to terminate
LruListen1.readyEvent.WaitOne();
// Read the Lru_SetChanFreq initialized from LruListen1,
// and continue processing it on Thread 1
Lru_operation LruOpX = new Lru_operation();
LruOpX.LruOperation(LruListen1.SetChanFreq);
}
public void LruOperation(Lru_SetChanFreq setChanFreq)
{
// Access the original Lru_SetChanFreq instance received as parameter
}
}
// this is starting point of thread #2
public class Lru_Listen
{
// Declare Lru_SetChanFreq as a field so as to access it externally
internal Lru_SetChanFreq SetChanFreq;
// Our thread synchronization event
internal ManualResetEvent readyEvent = new ManualResetEvent(false);
public void LruShowRequestData(// stuff )
{
this.SetChanFreq = new Lru_SetChanFreq();
SetChanFreq.SetFreq(); // calls to another class method
// Signal that we are ready
readyEvent.Set();
}
}
Update: I've edited my code to introduce proper thread synchronization (to replace the OP's while (LruListenThread.IsAlive) and Thread.Sleep(1)). This consists of three parts:
Creating a ManualResetEvent instance that can be accessed by both threads.
Calling WaitOne from Thread 1, in order to make it wait.
Calling Set from Thread 2 once it completes initializing your Lru_SetChanFreq, thereby signalling to Thread 1 that it may proceed.

Lock code section in c#

My question may sound like many others here but it has a flavor I didn't find.
I am trying to understand the following logic
A generic object
public class GenericClass
{
public static void DoSomething(Object lockObj)
{
lock(lockObj)
{
// do something here
}
}
}
Class A
internal class A
{
private static _aLock = new Object();
public void Do_A_Thing()
{
GenericClass.DoSomething(_aLock);
}
}
Class B
internal class B
{
private static _bLock = new Object();
public void Do_B_Thing()
{
GenericClass.DoSomething(_bLock);
}
}
I just hope to confirm if my explanation is correct:
If multiple threads of class "A" will attempt simultaneously access code in "genericClass" method "DoSomething", this method will be locked to all but one instance of class "A". But a single instance of class "B" will be able to proceed with execution any time. If class "B" will also have multiple instances execute, they will not interfere with class "A" locks.
Is this correct based on what you see above?
Yes, your description sounds correct. It is perhaps a little unusual to pass the lock object in, but it'll work fine. The only change I would suggest is to make the static fields readonly so you can't accidentally change the value to a different object reference.
Your conclusion is correct but it is not a good practice to pass locked object around. I suggest to put the lock inside class A and B respectively.
I suggest to write:
internal class A
{
private static readonly _aLock = new Object();
public void Do_A_Thing()
{
lock (_aLock)
{
GenericClass.DoSomething();
}
}
}
Do you have a specific reason to put the lock in another class? Maybe you can solve your problem in a different way?
Also keep in mind that in some conditions, maybe it is not your case, you can have a deadlock if class A and B call each other (A->B->A).
Yes, that is correct. The locks in A and the locks in B are completely unaware of each other. The code will only be blocked when there is another thread locking it with the same object as identifier.
If you are using generics, then something like
public class MyGadget<T>
{
static readonly SyncRoot = new object() ;
public T SynchronizedMethod()
{
lock ( SyncRoot )
{
SynchronizedMethodGuts() ;
}
}
}
should do what you want because MyGadget<Foo> and MyGadget<Bar> are different classes: they each have their own, different SyncRoot field.

All threads only in one method at a time?

I have several objects inheriting from ClassA, which has an abstract method MethodA.
Each of these inheriting objects can allow up to a specific number of threads simutaneously into their MethodA.
The catch: Threads can only be in an object's MethodA, while no other objects' MethodA is being processed at the same time.
How can I solve this? I am thinking about using a semaphore, but don't know exactly how to do it, because I just can't wrap my head around the problem enough to get a solution.
EDIT:
Example code (may contain syntax errors:)
public class ClassA
{
public virtual void MethodA{}
}
public class OneOfMySubclassesOfClassA // there can be multiple instances of each subclass!
{
public override void MethodA{
// WHILE any number of threads are in here, THIS MethodA shall be the ONLY MethodA in the entire program to contain threads
EDIT2: // I mean: ...ONLY MethodA of a subclass (not of a instance of a subclass) in the entire program...
}
}
...and more subclasses...
The derived type is used as type argument in the base class together with a static semaphore to get one semaphore shared between all instances of each subclass. And then there is some mess to ensure that only one type is active. A quick test indicates that this works correctly but there is an issue.
Assume for example that the method of ClassA1 is currently executing. If new request to execute this methods arrive with high frequency it may happen that other derived classes get no chance to execute because there are constantly new threads executing the method of class ClassA1.
internal abstract class ClassA<TDerived> : ClassA
{
private const Int32 MaximumNumberConcurrentThreads = 3;
private static readonly Semaphore semaphore = new Semaphore(ClassA<TDerived>.MaximumNumberConcurrentThreads, ClassA<TDerived>.MaximumNumberConcurrentThreads);
internal void MethodA()
{
lock (ClassA.setCurrentlyExcutingTypeLock)
{
while (!((ClassA.currentlyExcutingType == null) || (ClassA.currentlyExcutingType == typeof(TDerived))))
{
Monitor.Wait(ClassA.setCurrentlyExcutingTypeLock);
}
if (ClassA.currentlyExcutingType == null)
{
ClassA.currentlyExcutingType = typeof(TDerived);
}
ClassA.numberCurrentlyPossiblyExecutingThreads++;
Monitor.PulseAll(ClassA.setCurrentlyExcutingTypeLock);
}
try
{
ClassA<TDerived>.semaphore.WaitOne();
this.MethodACore();
}
finally
{
ClassA<TDerived>.semaphore.Release();
}
lock (ClassA.setCurrentlyExcutingTypeLock)
{
ClassA.numberCurrentlyPossiblyExecutingThreads--;
if (ClassA.numberCurrentlyPossiblyExecutingThreads == 0)
{
ClassA.currentlyExcutingType = null;
Monitor.Pulse(ClassA.setCurrentlyExcutingTypeLock);
}
}
}
protected abstract void MethodACore();
}
Note that a wrapper method is used to call the actual implementation in MethodACore. All the synchronization objects shared between all derived classes are in a non-generic base class.
internal abstract class ClassA
{
protected static Type currentlyExcutingType = null;
protected static readonly Object setCurrentlyExcutingTypeLock = new Object();
protected static Int32 numberCurrentlyPossiblyExecutingThreads = 0;
}
The derived classes will look like this.
internal sealed class ClassA1 : ClassA<ClassA1>
{
protected override void MethodACore()
{
// Do work here.
}
}
internal sealed class ClassA2 : ClassA<ClassA2>
{
protected override void MethodACore()
{
// Do work here.
}
}
Unfortunately I have no time to explain how and why this works in more detail right now but I will update the answer tomorrow.
public abstract class Foo
{
private static Type lockedType = null;
private static object key = new object();
private static ManualResetEvent signal = new ManualResetEvent(false);
private static int threadsInMethodA = 0;
private static Semaphore semaphore = new Semaphore(5, 5);//TODO set appropriate number of instances
public void MethodA()
{
lock (key)
{
while (lockedType != this.GetType())
{
if (lockedType == null)
{
lockedType = this.GetType();
//there may be other threads trying to get into the instance we just locked in
signal.Set();
}
else if (lockedType != this.GetType())
{
signal.WaitOne();
}
}
Interlocked.Increment(ref threadsInMethodA);
}
semaphore.WaitOne();
try
{
MethodAImplementation();
}
finally
{
lock (key)
{
semaphore.Release();
int threads = Interlocked.Decrement(ref threadsInMethodA);
if (threads == 0)
{
lockedType = null;
signal.Reset();
}
}
}
}
protected abstract void MethodAImplementation();
}
So there are a few key points here. First off, we have a static object that represents the only instance that is allowed to have threads. null means the next thread to come along can put in "their" instance. If another instance is the "active" one the current thread waits on the manual reset event until either there is no locked instance, or the locked instance changed to what might possibly be that thread's instance.
It's also important to count the number of threads in the method to know when to set the locked instance to null (setting to to null without keeping track of that would let new instances start while a few of the previous instances were finishing.
Locks around another key at the start and end are rather important.
Also beware that with this setup it's possible for one type to starve out other types, so if this is a heavily contended resource it's something to watch out for.
Assuming you have a list of all relevant instances, this code will lock on all other instances and thus allow only one instance's code to be executed at any given time:
void MethodA()
{
foreach (var obj in objects)
if (obj != this)
Monitor.Enter(obj);
try
{
// do stuff
}
finally
{
foreach( var obj in objects)
if (obj != this)
Monitor.Exit(obj);
}
}

Categories