Thread using delegate or function name - c#

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.

Related

Why do delegates in a none static class work like they are static C#

Hi I've modified some delegate tutorial code to experiment and I know there are prebuilt delegates available but without taking those into account.
I don't understand how the following works which I will break down:
class Program
{
static void Main(string[] args)
{
Human human1 = new Human(20);
BuffsProccessor buffsProccessor1 = new BuffsProccessor();
BuffsProccessor buffsProccessor2 = new BuffsProccessor();
BuffsCanAdd buffsCanAdd = new BuffsCanAdd();
BuffsProccessor.BuffHandler buffHandler = buffsCanAdd.AddStrengthBoost;
buffHandler += buffsCanAdd.AddIntelligenceBoost;
buffsProccessor1.ProcessBuffs(human1, buffHandler);
buffsProccessor2.ProcessBuffs(human1, buffHandler);
}
}
public class BuffsProccessor
{
public delegate void BuffHandler(Race race);
public void ProcessBuffs(Race race, BuffHandler buffHandler)
{
buffHandler(race);
race.ShowStats();
}
}
public class BuffsCanAdd
{
public void AddStrengthBoost(Race race)
{
System.Console.WriteLine("Adding strength boost");
}
public void AddIntelligenceBoost(Race race)
{
System.Console.WriteLine("Adding intelligence boost");
}
}
What I'm finding confusing is how come this line works like the class and delegate are static:
BuffsProccessor.BuffHandler buffHandler = buffsCanAdd.AddStrengthBoost;
the class and the delegate within the class are accessible without an instance of the BuffsProccessor class.
What is happening in memory when
BuffsProccessor.BuffHandler buffHandler = buffsCanAdd.AddStrengthBoost;
the buffHandler is there I'm finding this so confusing I'm struggling to form my question. Since the new keyword isn't being used how and where is it being stored in memory if it isn't in an instance of the BuffProccessorClass?
I hope this makes sense I can't find any delegate tutorials that answers this specific question.
What, do you mean, "without an instance of the BuffsProccessor class"? It's right there:
buffsCanAdd.AddStrengthBoost;
See that buffsCanAdd? That's your instance. If it were a static method you could just say AddStrengthBoost without the object before it.
The reason it works is that delegates don't just keep a reference to a method, they can also store a reference to the object to invoke the method on. This is mandatory for delegates to non instance methods, because you can't just invoke those methods on thin air.
As for your second question, there is a new involved, it's just that since C# 2, you can skip it and the compiler will put it for you. Before that, you had to do it by hand:
BuffsProccessor.BuffHandler buffHandler = new BuffsProccessor.BuffHandler(buffsCanAdd.AddStrengthBoost);
But now it's considered bad style.

What is an alternative to calling a function in a constructor in C#?

I am calling a function in my constructor in my C# class. The constructor gets called at design time, so instead of calling my function there, I thought of adding the OnLoad event and call my function from there instead. However, since I am new to C#, I am not sure how to do this, since I read that the OnLoad is for forms and I don't see a couple of solutions working (Load is not being recognized). How can I achieve loading the function without calling it in the constructor?
Below's an example of how to implement the Factory Pattern in order to create an instance of the class in question. The benefit here is that the SpecialMethod is called by your "API" and not the consumer of your "API." Ensuring SpecialMethod is always called; change behavior to suit your scenario ...
/* consumer (on your page load) */
var instance = SomeClass.GetInstance();
public class SomeClass
{
/* prevent consumers from directly instantiating `SomeClass` */
private SomeClass() {}
public static SomeClass GetInstance()
{
var instance = new SomeClass();
instance.SpecialMethod();
return instance;
};
private void SpecialMethod()
{
/* Special stufff ... */
}
}

Will Keyword NEW reinitialize all others running function value in 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.

OOP - how to call a function before the class constructor

I have a job interview tomorrow and I'm trying to answer this question:
There is a class named C and method m in this class, this class have also empty constructor:
Main ()
{
C c = new c();
}
Class C {
public c {
//empty constructor
}
public m {
//does something - doesnt mind
}
}
And what you have to do is to change the code so that in a creation of an instance class C, the method m would be called before the class constructor.
You have to do this without changing the main (edit only the class code).
Thanks in advance!
Like the other answers have said, you can make the method static. But then you need to explicitly call it. If you make a static class constructor, that will get called once automatically (you don't need to call it), the first time the class is referenced (like when you construct the first instance). You can't exactly control when it executes, but it will execute before the first instance is constructed. Based on the way they've worded the question (you can't change the Main method), I think static class constructor is the answer they're looking for.
http://msdn.microsoft.com/en-us/library/k9x6w0hc%28v=vs.80%29.aspx
Static constructors have the following properties:
A static constructor does not take access modifiers or have parameters.
A static constructor is called automatically to initialize the class before the first instance is created or any static members are
referenced.
A static constructor cannot be called directly.
The user has no control on when the static constructor is executed in the program.
Java doesn't have static class constructors, but they do have static initialization blocks..
static {
// code in here
}
To call a class's method before its constructor gets called you either have to turn this method into static so you don't need an instance of that class to call it, or (in C#) you can use FormatterServices.GetUninitializedObject Method to get an instance of your class without running the constructor (which of course may not be a wise thing to do).
In JAVA:
make method static and call your method in static block.
class C{
static{
m();
}
public C() {
System.out.println("Constructor Called..");
}
public static void m() {
System.out.println("m() is called.");
}
}
Main call
public static void main(String[] args) {
new C();
}
In both Java and C# you can use, base class constructors, static constructors (Edit: static initializer block in Java), and field initializers, to call code before the C class's constructor executes without modifying Main.
An example using a field initializer block in Java:
class C {
{ m(); }
public C() {
System.out.println("cons");
}
public void m() {
System.out.println("m");
}
}
This prints "m", then "cons". Note that m is called every time a C is constructed. A static initializer block would only be called once for the JVM.
Its basic OOP. You have to make a public static method and call it. That method can then call the constructor, or you can call the constructor directly from main.
Before you call the constructor, the object don't exist, therefore no instance methods exist, therefore nothing tied to the instance/object can be called. The only things that do exist before the constructor is called is the static methods.
Following way seems to achieve what is required. Without using static methods/variables
namespace FnCallBeforeConstructor
{
static void Main(string[] args)
{
MyClass s = new MyClass();
Console.ReadKey();
}
partial class MyClass: Master
{
public override void Func()
{
Console.WriteLine("I am a function");
}
public MyClass()
: base()
{
Console.WriteLine("I am a constructor");
}
}
class Master
{
public virtual void Func() { Console.WriteLine("Not called"); }
public Master()
{
Func();
}
}
}
Output is:
I am a function
I am a constructor

How can I use delegates to pass methods in a thread wrapper class?

I'm currently self-teaching myself C# and I'm a bit new at programming so apologies in advance if this is covered in another topic (I tried searching).
I've been trying to make a generic worker / thread class that takes in a method which specifically wraps around a long set of procedural steps. The idea is to be able to pause/resume it a manner similar to setting breakpoints to pause/unpause in Visual Studio. To provide context, I'm mostly working with automation with an ASP.NET and XAML WPF interface (XAML at the moment).
My understanding is that I need to use delegates of some sort but I'm looking for a very simple example in plain English. The examples I found are a completely different scope and I have a hard time following the provided solutions in other contexts.
From other examples on MSDN and Stackoverflow, the "Task" worker class is what I have so far, but I'm a bit at a loss on where to on DoDelegatedMethod and my constructor. What I'm trying to do here is to instantiate a Task object, pass in a delegated method on new instantiation, create a new thread, and marry the passed in method to the thread.
The reason why I want a general "Task" is so I can manage specific methods generically instead of having to write a different "DoWork" method for each instance.
Is this the right approach?
class Task
{
private ManualResetEvent _shutdownFlag = new ManualResetEvent(false);
private ManualResetEvent _pauseFlag = new ManualResetEvent(true);
private delegate void MyDelegate();
Thread _thread;
public Task() { }
public Task(MyDelegate d = new MyDelegate(DoStuff)) // ERROR
{
_thread = new Thread(DoDelegatedMethod); // ERROR
}
public void Start()
{
_thread.Start();
}
public void Resume()
{
_pauseFlag.Set(); ;
}
public void Stop()
{
_shutdownFlag.Set();
_pauseFlag.Set();
_thread.Join();
}
private void DoDelegatedMethod(MyDelegate d)
{
do
{
d();
}
while (!_shutdownFlag.WaitOne(0));
}
// This does nothing but spin forever until I force it to stop
public void Spin()
{
do
{
// MessageBox.Show("test");
_pauseFlag.WaitOne(Timeout.Infinite);
}
while (!_shutdownFlag.WaitOne(0));
//MessageBox.Show("thread over");
}
}
new Thread() takes a ThreadStart (or ParameterisedThreadStart) argument, and your DoDelegatedMethod callback doesn't have the right signature for ThreadStart. So you need to write something like this:
ThreadStart method = new ThreadStart(() => DoDelegatedMethod(d));
_thread = new Thread(method);
This creates an anonymous callback (the () => DoDelegatedMethod(d) bit) which when run will call DoDelegatedMethod with the delegate d (which is 'captured' by the anonmyous method). Now you pass this anonymous callback to the Thread constructor, so when the thread runs, it will call the anonymous callback, which will in turn call DoDelegatedMethod(d). Effectively the lambda adapts DoDelegatedMethod to the ThreadStart signature.
Another way to do this would be to change DoDelegatedMethod to take no arguments, and store d as a member field of the Task class which DoDelegateMethod would access.
Also, the reason you get an error on your constructor is that default values can only be of a limited set of types, and delegates aren't one of them (only types that are allowed in attributes, like int, long, string and Type are permitted). Use an overload instead:
public Task() : this(new MyDelegate(DoStuff)) { ... }
public Task(MyDelegate d) { ... }
Note you may still get an error if DoStuff is an instance method of Task -- it's not clear. Personally I think having a default delegate for Task to run is a bit of an odd design, so you may just want to get rid of the default constructor.
Following the discussion in the comments I thought it was worth summarising the suggested revisions to the Task class:
public class Task
{
private readonly Action _action;
// other members as before
// default constructor removed
public Task(Action action)
{
_action = action;
}
public void Start()
{
ThreadStart ts = new ThreadStart(DoDelegatedMethod);
_thread = new Thread(ts);
_thread.Start();
}
private void DoDelegatedMethod()
{
do
{
_action();
}
while (!_shutdownFlag.WaitOne(0));
}
// other members as before
}
And the usage:
Task task = new Task(this.AutomatedTasks);
task.Start();
private void AutomatedTasks() { ... }
You may find good implementation of Task Pool manager here
www.codeproject.com/KB/threads/smartthreadpool.aspx
smartthreadpool allows to send in pool any task,
but you have to add Pause\Start functions to it.
I would model this a List which I would enumerate like you would any other list and use 'yield' at the en of the enumerator.

Categories