I've modified my code to the point where it will execute, but it's linked to a timer, and will attempt to execute over and over till the timed condition is lost. I tried putting a "lock" on the system with a variable I named "intLimiter", to force the sequence to stop after one execution, but the lock doesn't seem to be working.
if (DateTime.Now.Hour == intAlarmHour && DateTime.Now.Minute == intAlarmMinute)
{
if (intLimiter == 1)
{
intLimiter = 2;
if (radTG.Checked)
{
System.Media.SoundPlayer sound = new System.Media.SoundPlayer(Properties.Resources.Celldweller___Tough_Guy);
sound.Play();
}
...
}
}
As of what I understand from your question, you want to separate the if statements to work all at the same time...
What you can do is create new 'Threads' for each statement which would make you able to run all of then at once...
For thread, make sure you include the namespace System.Threading.
using System.Threading;
Now what you should do with your code:
...
if (DateTime.Now.Hour == intAlarmHour && DateTime.Now.Minute == intAlarmMinute)
{
if (radTG.Checked == true)
{
Thread radTG = new Thread(radTGChecked);
radTG.Start();
}
...
}
...
public void radTGChecked() {
SoundPlayer sound = new SoundPlayer(Properties.Resources.Celldweller);
sound.PlaySync();
}
Do this to all the if statements following, and they will all run together, each on a thread...
Forgive me if that was not the answer of your question, but the title corresponding to the content does seem a little blurry to me...
But if it did, here's an article that will help you understand Multi-Threading.
Related
I don't know if this problem is Unity-specific so maybe other C# developers can help me too :)
So I am actually trying to implement my own version of the A* algorithm and to improve performance I want the actual path finding for every seeker to be multi threaded:
It works pretty well until the moment I activate a second seeker:
Like you can see it stops after 15 iterations (varying depending on how many text outputs i call -> I guess the threads are getting killed after a amount of time) in the algorithm and the first started thread gets kind of killed by the following.
I am using the C# ThreadPool class for my thread management but I tried also to use the Thread class. It is the same result.
Implementation of my threading:
public static void RequestPath(PathRequest _request)
{
Debug.Log("Queueing PathRequest...");
ThreadPool.QueueUserWorkItem(instance.StartThreadedPathfinding, _request);
}
The called method:
private void StartThreadedPathfinding(object _stateInfo)
{
PathRequest request = (PathRequest)_stateInfo;
m_pathfinder.FindPath(request, OnPathFound);
}
And FindPath:
public void FindPath(PathRequest _request, Action<PathResult> _callback)
{
Debug.Log("Starting A* Algorithm");
BinaryHeap<Node> openList = new BinaryHeap<Node>(GridSize);
HashSet<Node> closedList = new HashSet<Node>();
Node startNode = _request.Start;
Node targetNode = _request.Target;
bool success = false;
openList.Add(startNode);
while (openList.Count > 0)
{
Debug.Log(Thread.CurrentThread.ManagedThreadId + ": " + Thread.CurrentThread.ThreadState.ToString());
Node currentNode = openList.RemoveFirst();
if (currentNode == targetNode)
{
// TODO: Path found -> _callback
success = true;
Debug.Log("Path found");
_callback(new PathResult(null, success, _request.Callback));
return;
}
closedList.Add(currentNode);
foreach (Node neighbour in currentNode.m_neighbours)
{
if (closedList.Contains(neighbour))
{
continue;
}
int tentativeG = currentNode.m_gCost + GetDistance(currentNode, neighbour);
if (openList.Contains(neighbour) && tentativeG > neighbour.m_gCost)
{
continue;
}
neighbour.m_parent = currentNode;
neighbour.m_gCost = tentativeG;
neighbour.m_hCost = GetDistance(neighbour, targetNode);
if (openList.Contains(neighbour))
{
openList.UpdateItem(neighbour);
}
else
{
openList.Add(neighbour);
}
}
}
// TODO: No path to the target exists -> calculate some path
success = false;
Debug.Log("No existing path");
_callback(new PathResult(null, success, _request.Callback));
return;
}
RequestPath and StartThreadedPathfinding are in a class called PathRequestManager and FindPath is in an other class called Pathfinder.
Another point is that the threads don't just stop because of an error or sth like that but are still somehow running I think because after I started the scene in Unity I have to kill the Unity-process in the taskmanager because sth is stuck (CPU-Load is always about 80% when I have to do that)
Thought about deadlocks but couldn't find any.
I would be glad if someone could help me here and if you need more information about the source code feel free to ask :)
So I found the problem thanks to an answer in the Unity forums:
I was working on the same Grid and therefore on the same Nodes with every thread. When I was updating a Node in the algorithm on one thread while another one was working with the same Node some bad things happend and the result can be seen above in the question.
I solved this by cloning the grid for each thread and working on the grids owned by the threads.
First of all my question is quite complicated (for me) and I try to explain.
I have a WPF application which is working with NFC tags. Couple days ago this code was worked properly but now somethings messed up.
First I have a method which is reading data from NFC tag like this:
private void NFCCard_OnCardInserted()
{
CheckCard();
}
private bool CheckCard()
{
try
{
lock (_object)
{
NFCCard.Connect(CardReader, SHARE.Shared, PROTOCOL.T0orT1);
APDUPlayer player = new APDUPlayer(ApduListFile, NFCCard);
if (nfcFunction.NFCLogin(player))
{
string TempCompanyID = "";
//--Read data
}
DateTime cartOpenedDate = Convert.ToDateTime(OpenedDate);
if (CartNo == "" || CompanyID.ToString() == "" || Convert.ToInt32(limit) <= 0 || isactive == "False" || cartOpenedDate.ToShortDateString() != DateTime.Today.ToShortDateString() || CartType == "Staff")
{
Dispatcher.BeginInvoke(new Action(delegate
{
ShowCardNo(txtCardNo, "Geçersiz Kart!");
}));
}
else
{
//-- Some internal code
}
}
}
catch (Exception exc)
{
StationSession.WriteLog("write log bla bla", exc);
}
}
Now is the funny thing when I check the threads windows of VS two same thread try to run NFCCard_OnCardInserted() method at same time.
For this reason I put lock state but the problem is this method firing two times. And its make big trouble for me because the card transaction time is being double right now (almost 3 second for some transaction. I cannot explain to people you will wait with cart at cart reader like this :/ ). By the way I check whole page for this method reference, just this code should use this method.
NFCCard.OnCardInserted += new CardInsertedEventHandler(NFCCard_OnCardInserted);
So how can I fix this problem without workaround. Because I have several page and method which is using NFC cart thread. I need to find clear way for this problem. Thanks.
consider the following code that is executed in every instantiation of a certain class:
private void StartUpdateThread()
{
runUpdateThread = true;
Thread thread = new Thread(new ThreadStart(UpdateUsages));
thread.Priority = ThreadPriority.BelowNormal;
thread.Start();
}
public void UpdateUsages()
{
DateTime updateDateTime = DateTime.Now;
while (runUpdateThread)
{
if (updateDateTime <= DateTime.Now)
{
_cpuUsage.Add(DateTime.Now, GetCPUUsage());
if (_cpuUsage.Count == 61)
_cpuUsage.Remove(_cpuUsage.ElementAt(0).Key);
_ramUsage.Add(DateTime.Now, GetRamUsage());
if (_ramUsage.Count == 61)
_ramUsage.Remove(_ramUsage.ElementAt(0).Key);
updateDateTime = DateTime.Now.AddSeconds(15);
}
Thread.Sleep(15000);
}
}
After adding 2 or 3 values to each Dictionary it throws "an element with the same key already exists in the dictionary". This should be impossible since i'm doing Sleep after each loop.
I've tried, unsuccessfully, to prevent this problem by adding the updateDateTime variable.
I'm running out of ideas. Can anyone help me or explain me how this can happen?
Thanks
Are either _cpuUsage or _ramUsage static by any chance? Or perhaps you've assigned the same value to both of them? If you could give us a short but complete program which demonstrates the problem, it would make things a lot clearer.
On a side note, you seem to be hoping that your usage of ElementAt(0) will remove the earliest entry from the dictionary, but there's no guarantee of that.
From what you're doing, it looks like you'd be better off with a LinkedList<Tuple<DateTime, long>> or similar.
I have recently implemented a scrolling text across an area of limited screen estate using a timers repeating every 100ms, and some simple string appending.
However, after this very implementation, I have come to realise that my GUI is getting randomly bugged/corrupted after a certain while. That is to say that some widgets/windows become completely white, and eventually the entire GUI turns white and unclickable.
What is weird is that there is no error debug output at all.
Having said that, I am using Mono with GTK-Sharp for the application. Does anyone have an idea or a possible clue how and why this is happening?
If not, how can I further debug this properly?
Thanks, really appreciate it.
PS: Sometimes, it takes up to 1.5 hours for the thing to start corrupting, it has random timeframes for it to start happening.
This is my the code implemented that caused this issue:
void ScrollSyncTo(object sender, System.Timers.ElapsedEventArgs e)
{
//initial check if it fits nicely alr
if (sync_to_full_txt.Length <= sync_to_max_char)
{
sync_to_timer.Stop();
return;
}
//check for pause
if (sync_to_pause >= 0)
{
sync_to_pause--;
return;
}
//check direction
int temp_psn;
string temp_str;
if (sync_to_direction)
{
temp_psn = sync_to_posn + 1;
if (sync_to_full_txt.Substring(temp_psn).Length < sync_to_max_char)
{
sync_to_pause = sync_to_break_steps;
sync_to_direction = false;
sync_to_posn = sync_to_full_txt.Length - 1;
System.GC.Collect();
return;
}
else
{
temp_str = sync_to_full_txt.Substring(temp_psn, sync_to_max_char);
}
}
else
{
temp_psn = sync_to_posn - 1;
if (temp_psn + 1 < sync_to_max_char)
{
sync_to_pause = sync_to_break_steps;
sync_to_direction = true;
sync_to_posn = 0;
System.GC.Collect();
return;
}
else
{
temp_str = sync_to_full_txt.Substring(temp_psn - sync_to_max_char + 1, sync_to_max_char);
}
}
//lets move it
sync_to.Text = temp_str;
sync_to_posn = temp_psn;
}
To program in GTK with multiple threads, you have to do a couple things to make your program thread-safe. Here is short explanation using C.
I'm more familiar with GTK in C, but I'm assuming it works the same in GTK#. So you have to call GLib.Thread.Init() and Gdk.Threads.Init() at the beginning of your program, bracket your call to Application.Run() with Gdk.Threads.Enter() and Gdk.Threads.Leave(), and also make sure any GTK and GDK calls in background threads (not GTK signal handlers) are between Gdk.Threads.Enter() and Gdk.Threads.Leave().
System.Timers.Timer callbacks come from a threadpool thread, but GTK objects can only safely be accessed from the GTK thread. I would suggest using GLib.Timeout, which runs on the GTK thread.
I can't quite think of how to phrase the question to be precise, but hopefully my meaning will be clear. Do Control.SuspendLayout and Control.ResumeLayout keep count?
To put it another way, If I call SuspendLayout twice, and ResumeLayout once, is layout still suspended?
There's little reason left to get stuck on a question like this. The source code is available, titled "Reference Source". The best way to get it is with the .NET Mass Downloader. Not every .NET assembly has its source code published, your backup is the venerable Reflector.
Anyhoo, the source code looks roughly like this:
private byte layoutSuspendCount;
public void SuspendLayout() {
layoutSuspendCount++;
if (layoutSuspendCount == 1) OnLayoutSuspended();
}
public void ResumeLayout() {
ResumeLayout(true);
}
public void ResumeLayout(bool performLayout) {
if (layoutSuspendCount > 0) {
if (layoutSuspendCount == 1) OnLayoutResuming(performLayout);
layoutSuspendCount--;
if (layoutSuspendCount == 0 && performLayout) {
PerformLayout();
}
}
}
internal void PerformLayout(LayoutEventArgs args) {
if (layoutSuspendCount > 0) {
//...
return;
}
//etc...
}
So the answer to your question is: Yes.
If I call SuspendLayout twice, and ResumeLayout once, is layout still suspended?
No. Layout is resumed.