Delegate to an instance method cannot have null Intermittent on runtime - c#

I got this error and cannot understand this error.
I use win form and .net 3.5.
The problem is, this can be compiled and intermittent. Just shown today, so i guess this occur very rare (maybe once after 5000 run). I want to know what makes this error thrown, and any possible workaround.
Here is the example of how I implemented the code.
My application is multithread, and this method is singleton.
Exception type: System.ArgumentException
Exception message: Delegate to an instance method cannot have null 'this'.
Exception stack trace:
at System.MulticastDelegate.ThrowNullThisInDelegateToInstance()
at System.MulticastDelegate.CtorClosed(Object target, IntPtr methodPtr)
class Caller
{
private ClassA theA;
public Caller()
{
theA = new ClassA();
}
public void button_click()
{
theA.Execute(false);
}
public void button2_click()
{
theA.Execute( true );
}
}
interface IClassA
{
void ActionMinus();
}
class ClassA
{
public int VariableA = 0;
public void Execute( bool wait )
{
ClassB instanceB = new ClassB( this );
Thread thread = new Thread( instanceB.Action ) // error in here
{
Name = "Executor",
Priority = ThreadPriority.Highest
};
thread.Start();
if( wait )
thread.Join();
}
public void ActionMinus()
{
//someAction1
VariableA -= 2;
//someAction2
}
}
class ClassB
{
private readonly ClassA instanceA;
public ClassB( ClassA instance )
{
instanceA = instance;
}
public void Action()
{
//some other action3
instanceA.VariableA += 5;
//some other action4
instanceA.ActionMinus();
//some other action5
}
}

It looks like it works to me.
What is the context of your program?
I wrote a simple empty shell containing your code, but the program will end before the thread gets kicked off.
I had to add a Console.ReadKey() method.
Here is the whole code I used:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace DelegateToInstance {
class Program {
static void Main(string[] args) {
var obj = new Caller();
obj.button_click();
Console.ReadKey();
}
}
class Caller
{
private ClassA theA;
public Caller()
{
theA = new ClassA();
}
public void button_click()
{
theA.Execute(false);
}
public void button2_click()
{
theA.Execute( true );
}
}
interface IClassA
{
void ActionMinus();
}
class ClassA
{
public int VariableA = 0;
public void Execute( bool wait )
{
ClassB instanceB = new ClassB(this);
Thread thread = new Thread( instanceB.Action ) // error in here
{
Name = "Executor",
Priority = ThreadPriority.Highest
};
thread.Start();
if( wait )
thread.Join();
}
public void ActionMinus()
{
//someAction1
VariableA -= 2;
//someAction2
}
}
class ClassB
{
private readonly ClassA instanceA;
public ClassB( ClassA instance )
{
instanceA = instance;
}
public void Action()
{
//some other action3
instanceA.VariableA += 5;
//some other action4
instanceA.ActionMinus();
//some other action5
}
}
}
I hate downvoters, so I gave you an upvote.

Related

Referencing class' function from an element of a linked list C#

For a purpose of my university project I need to implement a cyclical linked list, which holds some specific elements. The problem: I want an element of the linked list to have a pointer to a function from the class which creates it. To show the problem in pseudo-C#:
using System;
class Game{
internal void state1(){
Console.WriteLine("Executing state1 code");
}
internal void state2(){
Console.WriteLine("Executing state1 code");
}
Element elem1 = new Elem(state1);
Element elem2 = new Elem(state2);
elem1.Call();
elem2.Call();
}
class Element{
FunctionPointer Call = null;
Element(FunctionPointer function){
Call = function;
}
}
I've tried to use a Delegate, but didn't quite get it right. Is it possible to somehow achieve this using Interfaces?
My delegate try:
using System;
public delegate void MyDelegate();
class Game{
internal void state1(){
Console.WriteLine("Executing state1 code");
}
internal void state2(){
Console.WriteLine("Executing state1 code");
}
Element elem = new Element(new MyDelegate(state1));
}
class Element{
MyDelegate functionPointer = null;
Element(MyDelegate func){
functionPointer = func;
}
}
There are a few ways to do this. Using a delegate would be something like...
public class Game
{
private Element _element = null;
public Game()
{
_element = new Element(state1);
}
internal void state1()
{
Console.WriteLine("Executing state1 code");
}
internal void state2()
{
Console.WriteLine("Executing state2 code");
}
}
public class Element
{
public delegate void FunctionPointer();
private FunctionPointer _function = null;
public Element(FunctionPointer function)
{
_function = new FunctionPointer(function);
_function();
}
}
using interfaces...
public interface IGame
{
void state1();
void state2();
}
public class Game : IGame
{
private Element _element = null;
public Game()
{
_element = new Element(this);
}
public void state1()
{
Console.WriteLine("Executing state1 code");
}
public void state2()
{
Console.WriteLine("Executing state1 code");
}
}
public class Element
{
private IGame _game = null;
public Element(IGame game)
{
_game = game;
_game.state1();
}
}
in my opinion interfaces are better

Mark a method for static use

How can I mark a method to use only if the class object was initialized as static?
For example:
public class A
{
public A()
{
}
public void DoIt()
{
{
public void DoItStatic()
{
}
}
public class B
{
private A _aa = new A();
private static A _aaStatic = new A();
public B()
{
}
public void SomeMethod()
{
_aa.DoItStatic(); //Generate Error for that.
_aaStatic.DoItStatic(); //it's fine
{
}
So, if someone tries to use _aa.DoItStatic(), where _aa is not initialized as static, we generate an error.
Is this possible?
Thanks!

A way to store a method in a variable?

Hello I am new to programming.
Basically I need to store a method A from class A in variable A from class B inside a method from class B but I cannot seem to find a way.
To give an example:
Class A
public void methodA()
{
*method*
}
Class B
Delegate variableA; //I believe using Delegate is wrong
public void methodB();
{
variableA = ClassA.methodA();
}
Then in Class B there would be another method that will utilize the variable with the stored method.
public void methodC();
{
variableA;
}
This isn't the exact code I have but this is basically the gist of it. Any help is appreciated :)
Edit: Thanks for the help everyone!
ClassA definition:
public class ClassA
{
public void MethodA()
{
Console.WriteLine("Hello World!");
}
}
ClassB definition:
public class ClassB
{
private Action VariableA { get; set; }
public void MethodB(ClassA classA)
{
VariableA = classA.MethodA;
}
public void MethodC()
{
VariableA();
}
}
Program definition:
static void Main(string[] args)
{
ClassA classA = new ClassA();
ClassB classB = new ClassB();
classB.MethodB(classA);
classB.MethodC();
Console.ReadLine();
}
Here is an example:
public class Test
{
private Action<int> hiddenMethod = new Action<int>((i) =>
{
Console.WriteLine(i);
});
public void PublicMethod(int i)
{
hiddenMethod(i);
}
}
And using it:
class Program
{
static void Main(string[] args)
{
Test t = new Test();
t.PublicMethod(21);
Console.Read();
}
}
Use reflection:
public class A
{
public void MethodA()
{
Console.WriteLine("MethodA");
}
public static void StaticMethodA()
{
Console.WriteLine("StaticMethodA");
}
}
public class B
{
MethodInfo mv = typeof(A).GetMethod("MethodA");
MethodInfo smv = typeof(A).GetMethod("StaticMethodA");
public void CheckA(bool useStatic)
{
if (useStatic) smv.Invoke(null, null);
else mv.Invoke(new A(), null);
}
}
class MainClass
{
[STAThread]
public static void Main(string[] args)
{
var b = new B();
b.CheckA(true);
b.CheckA(false);
}
}
See details in MSDN.

How to check that a thread is complete?

I am having a lot of trouble with this. Consider this example:
public class Test {
Thread t;
public Test() {
t = new Thread(ThreadFunction);
}
public void Start() {
t.Start();
}
private void ThreadFunction() {
Thread.Sleep(5000);
Console.WriteLine("Function Complete");
}
}
public static class Main {
public Main() {
Test test = new Test();
test.Start();
// sleep longer than my worker so it finishes
Thread.Sleep(10000);
// a place to place a breakpoint
bool breakPointHere = true;
}
}
Now, I see the output of the console.log, but when I inspect Test's thread object, I see that IsAlive is still true, and ThreadStatus = TheadStatus.Running. Why is this? I wish to detect that the thread is truly complete, but I am confused as to how it can still be considered running if ThreadFunction() completes?
EDIT 2:
I finally tracked down the cause, Updating the code, and am going to answer my own question
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApplication1 {
public abstract class Worker {
protected bool shutdown;
protected Thread t;
private bool _isStopped = true;
public bool IsStopped {
get {
return t.ThreadState == ThreadState.Stopped;
}
}
private bool _isPaused = false;
public bool IsPaused {
get {
return _isPaused;
}
}
private string stringRepresentation;
public Worker() {
t = new Thread(ThreadFunction);
stringRepresentation = "Thread id:" + t.ManagedThreadId;
t.Name = stringRepresentation;
}
public void Start() {
OnBeforeThreadStart();
t.Start();
}
public void ScheduleStop() {
shutdown = true;
}
public void SchedulePause() {
OnPauseRequest();
_isPaused = true;
}
public void Unpause() {
_isPaused = false;
}
public void ForceStop() {
t.Abort();
}
/// <summary>
/// The main thread loop.
/// </summary>
private void ThreadFunction() {
OnThreadStart();
while (!shutdown) {
if (!IsPaused) {
if (!OnLoop()) {
break;
}
}
Thread.Sleep(1000);
}
OnShutdown();
}
public abstract void OnBeforeThreadStart();
public abstract void OnThreadStart();
public abstract bool OnLoop();
public abstract void OnShutdown();
public abstract void OnPauseRequest();
public override string ToString() {
return stringRepresentation;
}
}
public class Test : Worker {
public override void OnBeforeThreadStart() {
Log.WriteLine(this + ": Thread about to be started...");
}
public override void OnThreadStart() {
Log.WriteLine(this + ": Thread Started!");
}
public override bool OnLoop() {
Log.WriteLine(this + ": I am doing the things...");
return true;
}
public override void OnShutdown() {
Log.WriteLine(this + ": Shutting down!");
}
public override void OnPauseRequest() {
}
}
public static class Log {
public delegate void LogDelegate(string text, string eventTime, Severity severity);
public static event LogDelegate OnWriteLine;
private static Queue<string> _pendingFileWrites = new Queue<string>();
public enum Severity {
Info,
Warning,
Error
}
public static void WriteLine(object line, Severity severity = Severity.Info) {
string eventTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
string formatted = "[" + eventTime + "]: " + line;
Console.WriteLine(formatted);
lock (_pendingFileWrites) {
_pendingFileWrites.Enqueue(formatted);
}
if (OnWriteLine != null) {
// this is the offending line:
OnWriteLine.Invoke((string)line, eventTime, severity);
}
}
public static void WriteToFile(string path) {
lock(_pendingFileWrites) {
StreamWriter sw = File.AppendText(path);
while(_pendingFileWrites.Count > 0) {
sw.WriteLine(
_pendingFileWrites.Dequeue()
);
}
sw.Close();
}
}
}
class Program {
static void Main(string[] args) {
List<Test> tests = new List<Test>();
for(int i = 0; i < 10; i++) {
Test test = new Test();
test.Start();
tests.Add(test);
}
// sleep a little bit so they do the things
Thread.Sleep(10000);
foreach (Test test in tests) {
test.ScheduleStop();
}
bool allStopped;
do {
allStopped = true;
foreach (Test test in tests) {
if (!test.IsStopped) {
allStopped = false;
break;
}
}
} while (!allStopped);
Console.WriteLine("Done!");
// a place to place a breakpoint
bool breakPointHere = true;
}
}
}
I think your original testing that lead you to believe .IsAlive would be true had some flaw in it, I tweaked your program in your question to the following to make it compile and to be able to see which thread it created.
public class Program
{
public class Test
{
Thread t;
public Test()
{
t = new Thread(ThreadFunction);
t.Name = "TestThread";
}
public void Start()
{
t.Start();
}
private void ThreadFunction()
{
Thread.Sleep(5000);
Console.WriteLine("Function Complete");
}
}
public static void Main()
{
Test test = new Test();
test.Start();
// sleep longer than my worker so it finishes
Thread.Sleep(10000);
// a place to place a breakpoint
bool breakPointHere = true;
}
}
here is a screenshot of the running threads from inside ThreadFunction
Here is a screenshot from the end of the program
Notice that there is no "TestThread" thread.
Here is a screenshot from the locals window
IsAlive is false.
Do you really need to sleep to wait for your thread to finish?
If you don't, a better and more robust solution would be using Thread.Join()
public static class Main {
public Main() {
Test test = new Test();
test.Start();
test.Join(); // Waits for test to complete
bool breakPointHere = true;
}
}
So it turns out that my issue was that my logging method was calling a UI thread function like so:
private void LogToForm(object line, string eventTime, Log.Severity severity) {
if (dataGridView_LogInfo.InvokeRequired) {
dataGridView_LogInfo.Invoke (
new Action<object, string, Log.Severity>(LogtoFormCallback),
new object[] { line, eventTime, severity }
);
} else {
LogtoFormCallback(line, eventTime, severity);
}
}
At the Invoke() line, the thread would hang forever. The solution was to replace it with BeginInvoke() instead.
EDIT: Also, my example was/is quite poor for this. I thought I didn't understand threads at a fundamental level, and that my examples would have been enough. Hopefully someone googles this though and has this same cause, and can try this solution.

abstract class and non-nullable value type

I'm trying to compile the code (More iterator fun with the producer/consumer pattern
) proposed by the guru 'Joe Duffy', for class producer / consumer, but this error is occurring:
(I'm using visual studio 2010 and net 4.0.3)
Program.cs(37,34): error CS0453: The type 'T' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'System.Nullable'
Program.cs(11,40): (Related location)
Program.cs(37,61): error CS0453: The type 'T' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'System.Nullable'
Program.cs(11,40): (Related location)
Program.cs(44,53): error CS0453: The type 'T' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'System.Nullable'
Program.cs(11,40): (Related location)
Is too much for my meager knowledge! Could someone suggest a solution?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace ProducerConsumerClass
{
class Program
{
public abstract class Producer<T>
{
public Producer()
{
worker = new Thread(new ThreadStart(this.ProductionCycle));
}
private Queue<T> buffer = new Queue<T>();
public Thread worker;
private bool done;
public bool Done
{
get
{
return done;
}
}
public IEnumerable<T> ConsumerChannel
{
get
{
if (done)
throw new InvalidOperationException("Production is not currently active");
while (!done)
{
Nullable<T> consumed = new Nullable<T>();
//BUG: compiler crashes when using lock(...) construct within iterator
Monitor.Enter(buffer);
if (buffer.Count == 0)
Monitor.Wait(buffer);
if (buffer.Count > 0)
consumed = new Nullable<T>(buffer.Dequeue());
Monitor.Exit(buffer);
if (consumed.HasValue)
yield return consumed.Value;
}
yield break;
}
}
public void BeginProduction()
{
done = false;
worker.Start();
}
public void EndProduction()
{
done = true;
lock (buffer)
{
Monitor.PulseAll(buffer);
}
}
private void ProductionCycle()
{
while (!done)
{
T t = ProduceNext();
lock (buffer)
{
buffer.Enqueue(t);
Monitor.Pulse(buffer);
}
}
}
protected abstract T ProduceNext();
}
public abstract class Consumer<T>
{
public Consumer(Producer<T> producer)
{
this.producer = producer;
worker = new Thread(new ThreadStart(this.ConsumerCycle));
}
private Producer<T> producer;
public Thread worker;
private bool done = false;
public bool Done
{
get
{
return done;
}
}
public void BeginConsumption()
{
done = false;
worker.Start();
}
public void EndConsumption()
{
done = true;
}
private void ConsumerCycle()
{
foreach (T t in producer.ConsumerChannel)
{
Consume(t);
if (done)
break;
}
}
protected abstract void Consume(T t);
}
class RandomNumberProducer : Producer<int>
{
public RandomNumberProducer()
: base()
{
rand = new Random();
}
private Random rand;
protected override int ProduceNext()
{
return rand.Next();
}
}
class RandomNumberConsumer : Consumer<int>
{
public RandomNumberConsumer(RandomNumberProducer p)
: base(p)
{
}
private static int counter = 0;
private int id = ++counter;
protected override void Consume(int t)
{
Console.Out.WriteLine("#{0}: consumed {1}", id, t);
}
}
static void Main(string[] args)
{
RandomNumberProducer p = new RandomNumberProducer();
RandomNumberConsumer c1 = new RandomNumberConsumer(p);
RandomNumberConsumer c2 = new RandomNumberConsumer(p);
RandomNumberConsumer c3 = new RandomNumberConsumer(p);
p.BeginProduction();
c1.BeginConsumption();
c2.BeginConsumption();
c3.BeginConsumption();
Thread.Sleep(2500);
c3.EndConsumption();
c2.EndConsumption();
c1.EndConsumption();
p.EndProduction();
}
}
}
You need to constrain T:
public abstract class Producer<T> where T : struct
public abstract class Consumer<T> where T : struct

Categories