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
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
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!
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.
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.
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