I'm running into a problem with my threading for my simple incremental game.
when I begin the thread it does not seem to be starting an actual thread so I get stuck in the endless loop in the thread RunThread method.
the way I'm doing threading in c# is inheriting from this base thread class somebody else on SO gave this code to allow you to inherit from Thread.
abstract class BaseThread
{
private Thread _thread;
protected BaseThread()
{
_thread = new Thread(new ThreadStart(this.RunThread));
}
// Thread methods / properties
public void Start() => _thread.Start();
public void Join() => _thread.Join();
public bool IsAlive => _thread.IsAlive;
// Override in base class
public abstract void RunThread();
}
that base thread is then inherited from. Person inherits from Base Thread.
abstract class Person : BaseThread
{
public BigInteger amt = new BigInteger(0);
public BigInteger pow = new BigInteger(1);
public BigInteger cost = new BigInteger(100);
public ResourceManagement res= ResourceManagement.Instance;
public static bool PeopleThreads = true;
public override void RunThread()
{
}
}
and at the lowest level, I have a Farmer this inherits from Person.
class Farmer : Person
{
public override void RunThread()
{
while (PeopleThreads)
{
Thread.Sleep(5000);
res.AddFood(amt * pow);
Thread.Sleep(5000);
res.AddFood(amt * pow);
res.subtractFromRes("Food", amt);
}
}
}
in my Thread manager class I am doing farmer.RunThread(); it seems to get me stuck in the while loop instead of creating a new thread. This is my first real attempt at c# threading ive done java threading before and thats why I wanted to be able to inherit from Thread. here is where I start my threads at.
class PeopleManager
{
Farmer farmers = new Farmer();
Lumberjack jacks = new Lumberjack();
Miner miners = new Miner();
private static PeopleManager people_Instance= new PeopleManager();
bool running = false;
static PeopleManager() { }//DO NOT PUT ANYTHING HERE
private PeopleManager() { }//DO NOT PUT ANYTHING HERE
public void StartThreads()
{
if (!running)
{
farmers.RunThread();
jacks.RunThread();
miners.RunThread();
running = true;
}
}
public static PeopleManager Instance { get{ return people_Instance; } }
I fixed my issue changed how I was running the threads from runThread to Start()
class PeopleManager
{
Farmer farmers = new Farmer();
Lumberjack jacks = new Lumberjack();
Miner miners = new Miner();
private static PeopleManager people_Instance= new PeopleManager();
bool running = false;
static PeopleManager() { }//DO NOT PUT ANYTHING HERE
private PeopleManager() { }//DO NOT PUT ANYTHING HERE
public void StartThreads()
{
if (!running)
{
farmers.Start(); //this instead of RunThread() made it run it
jacks.Start(); // run as a thread and not a method call
miners.Start();
running = true;
}
}
public static PeopleManager Instance { get{ return people_Instance; } }
Related
I've got a WPF RichTextBox that I'd like to get working as a log output for the app.
I have a static class Log with method to write to the WPF RTB. Of course, this doesnt work when a background thread call the method.
I've tried using BeginInvoke, which works until the app gets closed throwing an error 'System.Windows.Application.Current.get returned null'
What is the proper approach to updating WPF RichText from other threads. And further, I dont think this background thread is disposing properly, any recommendations?
public partial class MainWindow : Window
{
Worker worker = new Worker();
public MainWindow()
{
InitializeComponent();
Log.rtb_control = rtbLog; // pass RTB ref to Log
worker.Start();
}
}
public static class Log
{
public static RichTextBox rtb_Control;
public static void Add(string Text)
{
App.Current.Dispatcher.BeginInvoke((Action)(() =>
{
rtb_Control.AppendText($"{Text}\r");
}
}
}
public class Worker
{
bool _Enabled = false;
public Worker()
{
_Manager = new Thread(new ThreadStart(Thread_Manager));
_Manager.Start();
}
public void Start()
{
_Enabled = true;
}
void Thread_Manager()
{
while(true)
{
if(_Enabled) { Log.Add("Inside Thread"); }
Thread.Sleep(10000);
}
}
}
Example Code (I use Semaphore rather than lock to "lock" that bool member):
public class MsgSendHandler
{
private bool _isSocketSending = false;
private Semaphore _socketSendingSem = new Semaphore(1, 1);
public void Send(INetMsg msg)
{
// Add Msg To MsgQueue
TrySendNext();
}
private void SendCallback(IAsyncResult ar)
{
// Finish Send
_socketSendingSem.WaitOne();
_isSocketSending = false;
_socketSendingSem.Release();
TrySendNext();
}
private bool TrySendNext()
{
_socketSendingSem.WaitOne();
if (_isSocketSending)
return false;
_isSocketSending = true;
_socketSendingSem.Release();
// Socket Begin Send => SendCallback
return true;
}
}
Can I "lock" a value type like this? Is there any better solution?
Expanding on comment:
The way I created mutli-threaded functionality in Unity3D was to have a Dispatcher class that is called once per frame to run any Actions that have been added to a list.
Dispatcher.cs
A simple singleton class that holds the actions with an actual lock when looping through the actions.
public class Dispatcher
{
private static Dispatcher _instance;
public static Dispatcher Instance
{
get
{
if(_instance == null)
{
_instance = new Dispatcher();
}
return _instance;
}
}
private List<Action> _actions = new List<Action> ();
public void AddAction(Action action)
{
lock (_actions)
{
_actions.Add(action);
}
}
public void CompleteActions()
{
lock (_actions)
{
foreach (Action action in _actions)
{
action();
}
}
_actions.Clear();
}
public void ClearActions()
{
lock (_actions)
{
_actions.Clear();
}
}
}
DispatcherUpdate.cs
Another simple class that's added to a GameObject within the scene to call the Dispatcher to Complete the aquired Actions.
public class DispatcherUpdate : MonoBehaviour
{
private void Awake()
{
Dispatcher.Instance.ClearActions();
}
private void Update()
{
Dispatcher.Instance.CompleteActions();
}
}
Usage
Dispatcher.Instance.AddAction(() => TrySendNext());
This is the method I've used for Async multi-threading with SignalR
I am new to multi-thread programming in C#. My problem is that I don't know how to wait for a method that is being run on another thread to finish, before it can continue to the next line. For example, something like this
public class A
{
int i;
public A()
{
i = 0;
}
protected void RunLoop()
{
while(i < 100)
{
i++;
}
}
public void Start()
{
TimerResolution.TimeBeginPeriod(1);
runThread = new Thread(new ThreadStart(RunLoop));
running = true;
runThread.Start();
}
}
public class B
{
A classAInstance = new A();
A.Start();
Console.Writeline(i);
}
Right now, it prints 0 on the console, which is not what I want (i.e. i = 100).
What is the best way to do this? BTW, I don't have access to the runThread that is created in class A
Thanks.
EDIT:
It was a bit difficult to solve this problem without modifying a lot codes. Therefore, we ended up with adding a condition in the public void Start() with which it can decide whether to run the RunLoop in a separate thread or not. The condition was defined using an Enum field.
public void Start()
{
TimerResolution.TimeBeginPeriod(1);
running = true;
if (runningMode == RunningMode.Asynchronous)
{
runThread = new Thread(new ThreadStart(RunLoop));
runThread.Start();
}
else
{
RunLoop();
}
}
And
public enum RunningMode { Asynchronous, Synchronous };
Thanks everyone for help.
The preferred method is to use the Task Parallel Library (TPL) and use Task with await.
If you must use Threads, then use a ManualResetEvent or ManualResetEventSlim to signal the end of a method.
void Main()
{
var a = new A();
a.Start();
a.FinishedEvent.WaitOne();
Console.WriteLine(a.Index);
}
// Define other methods and classes here
public class A
{
ManualResetEvent mre = new ManualResetEvent(false);
int i;
public EventWaitHandle FinishedEvent
{
get { return mre; }
}
public int Index
{
get { return i; }
}
public A()
{
i = 0;
}
protected void RunLoop()
{
while (i < 1000)
{
i++;
}
mre.Set();
}
public void Start()
{
var runThread = new Thread(new ThreadStart(RunLoop));
runThread.Start();
}
}
Your life would be so much better with tasks.
Your code could be this simple:
var task = Task.Factory.StartNew(() =>
{
var i = 0;
while (i < 100)
{
i++;
}
return i;
});
Console.WriteLine(task.Result);
I like use Monitor.Wait() and Monitor.Pulse() in conjunction with "lock" operator. It works, but you must be careful, when you use this technique.
I'm added some changes to your code to demonstrate it. Code below are prints i== 100, as you want.
public class A
{
int i;
public object SyncObject
{ get; private set; }
public A()
{
SyncObject = new object();
i = 0;
}
protected void RunLoop()
{
while (i < 100)
{
i++;
}
lock (SyncObject)
{
Monitor.Pulse(SyncObject);
}
}
public void Start()
{
var runThread = new Thread(new ThreadStart(RunLoop));
runThread.Start();
}
public void PrintI()
{
Console.WriteLine("I == " + i);
}
}
public class B
{
public static void Run()
{
A classAInstance = new A();
lock (classAInstance.SyncObject)
{
classAInstance.Start();
Monitor.Wait(classAInstance.SyncObject);
}
classAInstance.PrintI();
}
}
I have created a class, SenderClass, which will start and run a background worker from its constructor.
The method, RunWorker(), runs is a while(true) loop which will pop elements from a queue, send them through the method SendMessage(), and sleep for a small amount of time to allow new elements to be added to the queue.
Here lies the problem: How do I test the method that sends the element from the queue, without exposing it to those who uses the class?
Implementation:
public class SenderClass : ISenderClass
{
private Queue<int> _myQueue = new Queue<int>();
private Thread _worker;
public SenderClass()
{
//Create a background worker
_worker = new Thread(RunWorker) {IsBackground = true};
_worker.Start();
}
private void RunWorker() //This is the background worker's method
{
while (true) //Keep it running
{
lock (_myQueue) //No fiddling from other threads
{
while (_myQueue.Count != 0) //Pop elements if found
SendMessage(_myQueue.Dequeue()); //Send the element
}
Thread.Sleep(50); //Allow new elements to be inserted
}
}
private void SendMessage(int element)
{
//This is what we want to test
}
public void AddToQueue(int element)
{
Task.Run(() => //Async method will return at ones, not slowing the caller
{
lock (_myQueue) //Lock queue to insert into it
{
_myQueue.Enqueue(element);
}
});
}
}
Wanted interface:
public interface ISenderClass
{
void AddToQueue(int element);
}
Needed interface for test purpose:
public interface ISenderClass
{
void SendMessage(int element);
void AddToQueue(int element);
}
There's a very simple solution, saying I have created my class incorrect due to the Single Responsability Principle, and my class' purpose is not to send messages, but actually run what sends them.
What I should have, is another class, TransmittingClass, which exposes the method SendMessage(int) through its own interface.
This way I can test that class, and SenderClass should just call the method through that interface.
But what other options do I have with the current implementation?
I can make all private methods I wish to test (all of them) have a [assembly:InternalsVisibleTo("MyTests")], but does a third option exist?
Send message logic should be implemented in a separate class with a separate interface. This class should take the new class as a dependency. You can test the new class separately.
public interface IMessageQueue
{
void AddToQueue(int element);
}
public interface IMessageSender
{
void SendMessage(object message);
}
public class SenderClass : IMessageQueue
{
private readonly IMessageSender _sender;
public SenderClass(IMessageSender sender)
{
_sender = sender;
}
public void AddToQueue(int element)
{
/*...*/
}
private void SendMessage()
{
_sender.SendMessage(new object());
}
}
public class DummyMessageSender : IMessageSender
{
//you can use this in your test harness to check for the messages sent
public Queue<object> Messages { get; private set; }
public DummyMessageSender()
{
Messages = new Queue<object>();
}
public void SendMessage(object message)
{
Messages.Enqueue(message);
//obviously you'll need to do some locking here too
}
}
Edit
To address your comment, here is an implementation using Action<int>. This allows you to define your message sending action in your test class to mock the SendMessage method without worrying about creating another class. (Personally, I'd still prefer to define the classes/interfaces explicitly).
public class SenderClass : ISenderClass
{
private Queue<int> _myQueue = new Queue<int>();
private Thread _worker;
private readonly Action<int> _senderAction;
public SenderClass()
{
_worker = new Thread(RunWorker) { IsBackground = true };
_worker.Start();
_senderAction = DefaultMessageSendingAction;
}
public SenderClass(Action<int> senderAction)
{
//Create a background worker
_worker = new Thread(RunWorker) { IsBackground = true };
_worker.Start();
_senderAction = senderAction;
}
private void RunWorker() //This is the background worker's method
{
while (true) //Keep it running
{
lock (_myQueue) //No fiddling from other threads
{
while (_myQueue.Count != 0) //Pop elements if found
SendMessage(_myQueue.Dequeue()); //Send the element
}
Thread.Sleep(50); //Allow new elements to be inserted
}
}
private void SendMessage(int element)
{
_senderAction(element);
}
private void DefaultMessageSendingAction(int item)
{
/* whatever happens during sending */
}
public void AddToQueue(int element)
{
Task.Run(() => //Async method will return at ones, not slowing the caller
{
lock (_myQueue) //Lock queue to insert into it
{
_myQueue.Enqueue(element);
}
});
}
}
public class TestClass
{
private SenderClass _sender;
private Queue<int> _messages;
[TestInitialize]
public void SetUp()
{
_messages = new Queue<int>();
_sender = new SenderClass(DummyMessageSendingAction);
}
private void DummyMessageSendingAction(int item)
{
_messages.Enqueue(item);
}
[TestMethod]
public void TestMethod1()
{
//This isn't a great test, but I think you get the idea
int message = 42;
_sender.AddToQueue(message);
Thread.Sleep(100);
CollectionAssert.Contains(_messages, 42);
}
}
It looks like SenderClass should not perform any sending at all. It should simply maintain the queue. Inject an Action<int> through the constructor that does the sending. That way you can move SendMessage somewhere else and call it however you like.
As an added benefit your test of SendMessage is not cluttered with queue management.
Seeing your edit you don't seem to like this approach and you don't seem to like the InternalsVisibleTo approach either. You could expose SendMessage through a separate interface and implement that interface explicitly. That way SendMessage is still callable through that interface but by default it is not accessible without some casting contortions. It also does not show up in the intellisense autocomplete list.
Can I create a class that inherited from thread class in c#, for my Windows Phone application.
For example :
if my class name is 'MyClass' I want to start the thread as new MyClass().Start();
Like in following Java example
public class TagIndexer
{
private static class Task
{
private String docId;
private String tags;
private String extension;
public Task(String docId, String tags, String extension)
{
this.docId = docId;
this.tags = tags;
this.extension = extension;
}
}
private static final LinkedList<Task> queue = new LinkedList<Task>();
private static boolean isWorking = false;
private static class TaskRunner extends Thread
{
#Override
public void run()
{
while (true)
{
Task task;
synchronized (queue)
{
task = queue.poll();
if (null == task)
{
isWorking = false;
break;
}
isWorking = true;
}
/*
* PROCESSING CODE
*/
}
}
}
public static void addDocument(int docId, String tags, String extension)
{
Task task = new Task(Integer.toString(docId), tags, extension);
synchronized (queue)
{
queue.add(task);
if (!isWorking)
{
new TaskRunner().start();
}
}
}
}
new MyClazz().Start();
-
public abstract class MyThread
{
public abstract void Run();
public void Start()
{
new Thread(Run).Start();
}
}
public class MyClazz : MyThread
{
public override void Run()
{
Console.WriteLine("Hello World");
}
}
On Windows Phone, Thread is a sealed class, therefore you cannot inherit from it. If you want to keep the task-based approach, you can just create a class that will wrap a thread instance. Something like:
public abstract class Task
{
protected Thread InternalThread { get; set; }
protected abstract void Run();
public void Start()
{
this.InternalThread = new Thread(this.Run);
this.InternalThread.Start();
}
}
Of course, it's just an example. You would have to add some synchronization mechanism to prevent the Start method from creating multiple threads if called more than once.
Then you can inherit it to create custom tasks:
public class MyTask : Task
{
protected override void Run()
{
// Do something
}
}
See this article about BackgroundAgent from MSDN:
Background Agents Overview for Windows Phone