I am currently for the first time in need to rewrite my app into library. I have succes so far, but I need to somehow make auto repeated process, which could be started by simply camShield.start().
But I am not able to reference the enabled from anywhere. The idea here is that I would start thread with timer, which would be checking on the enabled variable. But to do that, I need another function, like stop(), which would set the enabled variable to false.
Is there any better way to implement such a function?
---EDIT----
I need to write functions CamShield.start() and CamShield.stop(), which would be able to access the CamShield.enabled variable.
Here is part of code, where I am trying to solve it (It is Class Library)
using SharpAdbClient;
using System;
using System.Diagnostics;
using System.Threading;
namespace BaReader
{
public class Private
{
public class CamShield
{
internal bool enabled = true;
public static void start()
{
new Thread(() =>
{
Thread.CurrentThread.IsBackground = true;
Timer camShieldTimer = new Timer(tap, null, 0, 20000);
}).Start();
}
}
internal static void tap(Object o)
{
AdbClient.Instance.ExecuteRemoteCommand("input tap 600 900", Device.lookup(), null);
Debug.WriteLine("Tapped");
}
}
}
Thanks in advance for any ideas.
You have declared methods static and your variable enabled as non static so you were not able to access it,
public class CamShield
{
internal bool enabled = false;
public void start()
{
if(!enabled)
{
enabled = true;
//your code to start
}
}
public void stop()
{
if(enabled)
{
//your code to stop
enabled = false;
}
}
}
I am sure you can instantiate the CamShield class and access start and stop methods from outside.
In order to stop the thread, you need to kill it using Abort. The attached question will provide you with enough tools and knowledge to get there.
second, you cannot access the enabled because of your scope. Take another look at the code:
public class Private
{
public class CamShield
{
internal bool enabled = true;
public static void start()
{
new Thread(() =>
{
Thread.CurrentThread.IsBackground = true;
Timer camShieldTimer = new Timer(tap, null, 0, 20000);
}).Start();
}
}
internal static void tap(Object o)
{
AdbClient.Instance.ExecuteRemoteCommand("input tap 600 900", Device.lookup(), null);
Debug.WriteLine("Tapped");
}
}
Your internal bool enabled is in the scope of CamShield class and won't be available to your tap method unless you initialize CamShield Class.
in order to use your internal bool enabled you need to declare it in your private class and then use it in tap:
public class Private
{
internal bool enabled = true;
public class CamShield
{
enabled = false;
public static void start()
{
new Thread(() =>
{
Thread.CurrentThread.IsBackground = true;
Timer camShieldTimer = new Timer(tap, null, 0, 20000);
}).Start();
}
}
internal static void tap(Object o)
{
enabled = true;
AdbClient.Instance.ExecuteRemoteCommand("input tap 600 900", Device.lookup(), null);
Debug.WriteLine("Tapped");
}
}
Related
I wrote code about the settings page that uses static bool
then I need to Check If the public static bool changed or not In the form that I needed to call
(Form1 Is main form and Can be opened Once But Form2 Can open >1)
then I wrote this code
Form1:
private static bool Called = false;
public static bool HideButton
{
get { return Called; }
set
{
if (Called != value)
{
Called = value;
Update(); //function about updating buttons
}
}
}
Form2:
private void checkBox5_CheckedChanged(object sender, EventArgs e) {
if (checkBox5.Checked)
{
Form1.HideButton = true;
}
else
{
Form1.HideButton = false;
}
}
Then it said that you can't run non-static inside static
So I have an idea If I can check public static bool then call async void that is not static.
any idea?
Well, static means not instance, so you have one and only one Called value for all Form1 instances.
When you try to call Update() within static property set, the compiler complains: it doesn't know on which
instance should it be called (imagine, that there are three opened Form1).
You can either add some logic, e.g. let call Update on all opened Form1:
using System.Linq;
...
private static bool Called = false;
public static bool HideButton
{
get { return Called; }
set
{
if (Called != value)
{
Called = value;
// Assuming WinForms
// We call Update on all opened Form1 forms
foreach (var form in Application.OpenForms.OfType<Form1>())
form.Update();
}
}
}
Or you may let each Form1 instance have its own Called, i.e. drop static:
private bool Called = false;
public bool HideButton
{
get { return Called; }
set
{
if (Called != value)
{
Called = value;
Update();
}
}
}
Please, note, that async is quite a different conseption which is orthogonal to static
Don't now if title is clear. Here is a piece of code from a class in charge of managing a long operation :
public class LongProcess
{
public delegate void RunningChangedEventHandler(bool running);
public event RunningChangedEventHandler RunningChanged;
private object runningLock = new object();
public bool Running
{
get { lock (runningLock) { return mRunning; } }
set
{
lock (runningLock)
{
RunningChanged.Invoke(value);
value = mRunning;
}
}
}
public void start()
{
mWorker = new BackgroundWorker();
mWorker.DoWork += Bg_DoWork;
mWorker.RunWorkerAsync();
}
private void Bg_DoWork(object sender, DoWorkEventArgs e)
{
Running = true;
// Some things to do here ... but I need Running to be equals to true and it is not
}
}
In main programm, I use LongProcess to start some tasks, it is completed by report progression etc ...
The only problem I'm facing, is that it seems that I'm unable to set "Running" to true. Even right after the call to the setter, it still keeps its old value.
Any help and explanations on how this works will be greatly appreciated !
You have your value and field the wrong way around in the setter. You need this:
public bool Running
{
get { lock (runningLock) { return mRunning; } }
set
{
lock (runningLock)
{
RunningChanged.Invoke(value);
mRunning = value; // <=== LOOK HERE
}
}
}
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; } }
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.
This is what I want to do:
Have a timer with some interval
In the timer callback code, if some condition is met, another thread should be run
I’ve put my code in a class which is instantiated by the main form and the code is executed upon method call (‘StartSync()’, se sample code).
The problem is that the code runs for a couple of seconds but then terminates. I suppose I’m doing something stupid but I really can’t see what it is. Thankful for any help with regards to this.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Diagnostics;
namespace WindowsFormsApplication1
{
class Syncer
{
static bool SYNC_IN_PROGRESS;
public void StartSync()
{
SYNC_IN_PROGRESS = false;
Timer timer = new Timer(timerCallback, null, 0, 1000);
}
public void timerCallback(Object stateInfo)
{
Debug.WriteLine("Sync?");
if (!SYNC_IN_PROGRESS)
{
SYNC_IN_PROGRESS = true;
Thread thSync = new Thread(new ThreadStart(sync));
thSync.Start();
}
}
void sync()
{
Debug.WriteLine("Syncing...");
SYNC_IN_PROGRESS = false;
}
}
}
At a guess, the Timer is only held in a method variable; it sounds to me like the Timer is getting garbage collected and finalized, hence terminated. I suspect you should hold onto that reference in a field to prevent collection.
As an aside - I doubt it is the cause here, but when dealing with threading you should be religiously aware of access to shared state from multiple threads; for example:
using Monitor (aka lock)
appropriate use of volatile
Interlocked when it fits
Your current access to the static bool will probably work OK, but...
Try this cleaner approach
static volatile bool SYNC_IN_PROGRESS;
static thread syncPoll;
public void StartSync()
{
SYNC_IN_PROGRESS = false;
syncPoll = new Thread(sync);
syncPoll.Start();
}
void sync()
{
while (true)
{
Debug.WriteLine("Sync?");
if (SYNC_IN_PROGRESS) Debug.WriteLine("Syncing...");
Thread.Sleep(1000);
}
}
It does the same you try to do with your current code :) but doesn't use a timer
So here is what I did and it seems to work just fine
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
StartSync();
}
static bool SYNC_IN_PROGRESS;
public void StartSync()
{
SYNC_IN_PROGRESS = false;
System.Threading.Timer timer = new System.Threading.Timer(timerCallback, SYNC_IN_PROGRESS, 0, 1000);
}
public void timerCallback(Object stateInfo)
{
Debug.WriteLine("Sync?");
if (!(bool)stateInfo)
{
SYNC_IN_PROGRESS = true;
Thread thSync = new Thread(new ThreadStart(sync));
thSync.Start();
}
}
void sync()
{
Debug.WriteLine("Syncing...");
SYNC_IN_PROGRESS = false;
}
}