sorry if this is a silly question, I am new to C#, so please give me a break.
I am working on Revit API. currently, Revit API doesn't support multi-threading operations.
my question is how to stop a loop without calling a new thread?
I am trying to get a snapshot and I am waiting for the user to pick a snap, so I put an infinite loop till the condition meets
while (!Clipboard.ContainsImage()) //loop till user get a clipboard image
{
}
but what if I want to abort this???
I have tried
private void Abort_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Escape)
{
abort = true;
}
}
but this method requires threading ....any suggestions!!
You want to look into asynchronous processing patterns in Revit - check for instance The Building Coders description of IExternalEvent.
It might take a little while to wrap your head around it, but let me try to explain:
Split your code up into two parts: The first part runs up until the moment you ask the user to pick a snap (I'm assuming this happens in another application?). In a separate thread, poll the clipboard (or register your application as a clipboard viewer) in your while loop. Don't forget to Sleep() while you're polling! As soon as your polling thread finds a picture, create an instance of an IExternalEvent subclass and post it to Revit. When Revit has some spare time, it will execute the Execute method, passing in a UIApplication that you can use to do the rest of your code.
Revit doesn't let you access it's API from multiple threads at the same time, but during the Execute method of an IExternalEvent subclass, you are guaranteed to be in the correct thread for running code.
You can also look into the OnIdling event - basically, this gets called each time Revit has some spare time too. So instead of using a while loop in a separate thread, you could just place your clipboard checking code in the event handler for the OnIdling event and create a mechanism (a flag) to tell you wether you are currently waiting for a snap or not...
Related
I'm writing a program to help with a game. I need it to update the text box that shows the current exp value, on the forum load it does show the exp, I need it to update the exp like every 3 seconds.
How would I go about doing that?
Here is what I have so far:
Client C = Client.GetClients()[0];
Player P;
P = C.GetPlayer();
expTextBox.Text = ("Experience: " + P.Experience.ToString());
I am not sure if I need a timer (which i have tried and I am very bad at making) or if a backGroundWorker would be best.
Based on your comments, I would recommend that you update your UI when your player/s are attacking, and not use a timer. This will keep your UI the most up-to-date and will probably serve you better than a 3 or 10 second timer. You will have a method like this:
public void Attack(Enemy e)
{
//do your attack code
//did the enemy die?
KillEnemy();
//add exp just for landing a successful attack
AddExp(e);
}
public void AddExp(Enemy e)
{
CurrentPlayer.Exp += e.ExperienceGain;
//update the UI with the new exp
GameWindow.ExperienceBox.Text = CurrentPlayer.Exp;
}
This is of course more pseudocode, because I have no idea what your design looks like, but I've made quite a few games, and this is how I always do it.
Good Luck!
I would encourage you to use Timer if you go to the background worker with infinite loop that is okay but you need to take care of two things when you use background workers:
Updating textbox or any other UI won't work as it needs to be done from the main thread. so you need to check myTextbox.requireInvoke() function before.
Check if the background worker got a cancel signal to exist the infinite loop.
on the other side. you will consume some time when you use timers to update the text box. as the timer would go to the event processing cycle in the windows then fire the event and finally you will write the code in the timer event.
I am a bit new to threading (not new to C#, just haven't done much threading). Can someone explain to me why this does not work?
I have a thread which calls a method I will call "Loop". Loop contains a while loop which will continuously run, and on every loop of the while I want it to check if the A Key is down (using Microsoft's Keyboard class within the XNA Framework). But for some reason it never registers that anything is being pressed.
static Thread thread = new Thread(Loop);
static bool abort = false;
public static void Begin()
{
thread.Start();
}
private static void Loop()
{
while (!abort)
{
if (Keyboard.GetState().IsKeyDown(Keys.A))
Console.WriteLine("A pressed.");
}
}
Might anyone know why the Console.WriteLine() is never being called?
EDIT:
I guess I should explain a little bit. What I am actually trying to do is create something similar to ActionScript's events in C#. So I want to pass a "condition" and an "action" to call if that condition is met in this separate class which contains this thread. What this would do would allow me to just add "event listeners" to objects and it would automatically constantly check if one of the events gets triggered, rather than leave it to me to write If statements in code to check for the events.
Upon trying to do so, the first thing I tested was regarding this XNA Keyboard stuff, because it was one of the reasons I originally wanted to build this system, but it didn't work. So I created the standalone code which i posted above to see if I had made an error in my previous code and it still didn't work.
I never use XNA so I didn't really "know" but I've run into similar situations where you can't get keyboard (and other) input from a worker thread. I googled and found that in XNA this does seem to be the case. See this for example
So you need to (and probably want to) process your game input in the GUI thread. Just checking for input on each update tick should be fine. I doubt even if it did work, you would gain any performance - and you might introduce some interesting synchronization bugs ;-)
It does look like your creating your worker thread properly - this just isn't an application for it.
Suppose that we have the code shown below,
LoadOperation lop=_dsrvX.Load(_dsrvX.GetUserDetails(userID));
lop.Completed +=(s,a)=>
{
Debug.WriteLine("Completed but,
First I load it then I registered Completed evet!");
}
I see this type code everywhere so I wonder is it right?
As I know when you call domainService methods this automatically fills domain service object's related EntitySet.
Suppose that LoadOperation(Can be Submit,Invoke ops.) completed rapidly and when I passed to the next line where I register completed event everything has done.Is it possible? It seems hard to achive that but can you give me 100% guarantee?
If you can't guarantee that I'm asking if there is a method of calling OperationBase objects manually?
Any comment will be appreciated.
Well, this is a crazy world, I would not give 100% guarantee of anything :P - But I do not think it should be a problem. If this bothers you, you can pass the callback as a parameter, like this:
_dsrvX.Load(_dsrvX.GetUserDetails(userID), userDetailsCallBack, null);
(...)
void userDetailsCallBack(LoadOperation<UserDetails> op)
{
//do anything with the results
}
or, to simplify even further:
_dsrvX.Load(_dsrvX.GetUserDetails(userID), (op)=>
{
//do anything with the results
}, null);
Yes you can trust it - 100% guaranteed!
If you dig into the code behind the asynchronous Load method, you will see that it starts up another thread, to do the actual load, then returns immediately.
That separate thread then prepares for a service call, performs the service call, and eventually returns the resulting data.
It cannot trigger the Completed event until that is all done and we are talking "a lot" of code to get through, not to mention waiting on a web-service, whereas the return is pretty much instantaneous after the thread was started. i.e. no chance for the other thread to complete and interrupt it.
There is 0% chance that the load will complete before you add the handler on the next line.
The usual approach is to provide a callback or anonymous method instead, but your existing code is fine. MS knew what they were doing when the designed it that way :)
I had this argument with Jon Skeet, on a related question, and his reaction was that you don't know what the Load method is doing so it "might" happen faster than the return... My pragmatic answer was that we know exactly what is going on, by design, and it 100% returns before the Load even commences
I have a winform application that can get pretty unresponsive during heavy calculations. For example, when user presses F10 key, the program will starts some heavy stuff and remains unrsponsive for a while (I know this is not a desired way of program flow but I don't want to alter the way program works at the moment).
Now the problem is, during this time if user presses F10 again, the program will start doing the same thing as soon as it has done the first process.
How to disable capturing keys at a certain point and enable it again?
The program is not "capturing the key", it is queued by the operating system because your main UI-Thread is busy with your calculations and doesn't handle anything at that time. The only thing i could think of what you could do is to check that a certain time has elapsed after the last run has finished before you allow another run. An ugly hack in my humble opinion.
But, yeah, thats why you should use backgroundworkers or threading. Using a BackgroundWorker is a lot easier than it may seem at the beginning.
Ideally you should use a BackgroundWorker here but as you said
I don't want to alter the way program works at the moment).
So I won't go into that path.
What you can do is when you detect F-10 for the first time set a bool value to true and next time whenever you detect f-10, check if the bool is already true or not. If it is already true don't start the heavy operation again simply skip the code.
At the end of heavy processing set the bool to false again.
I would agree with Jason on the whole - hacks and temporary fixes have a nasty habit of becoming 'features' of a program.
However, to answer your question, I would suggest having a disable flag in your program that disables the desired functionality whilst your calculations are running. You could then put in the event handler a check for the flag :
public bool DisableFlag { get; set; }
public void MyKeyEventHandler(object sender, EventArgs e)
{
if (DisableFlag)
{
return;
}
// Do stuff
}
Hope that helps!
Cheers,
Chris.
EDIT :
Thinking about Ken's comment, and this is true, the event will be queued and it will only be useful as long as some events are bleeding through. So, the other option is to disable the even handler altogether by doing
myControl =- MyKeyEventHandler;
and then
myControl =+ MyKeyEventHandler;
when the calculations are finished. This way, no events are queued and you avoid the problem as described by Ken!!
Say I have 2 methods. One is an method triggered by the selected index changing in the listbox. The second method helps by clearing all textboxes, setting listbox index to -1, and setting the focus.
Question:
Method two executes, during the code it changes the selected index of the listbox to -1, thereby setting off the event trigger for the 1st method. Does Method 2 HALT it's own execution and transfer the process to the event, and then return back to its work after Method 1 is finished... OR does method 2 finish its entire codeblock then transfer to Method 1 since the selected index changes?
The first case.
Let's leave threads out of it for a moment, particularly because they're not involved in your scenario.
You're talking about properties and methods, but underneath it all, it's all just functions. When one function invokes another, control in your program transfers to the called function. When that function finishes running, control returns to the point where it was called. Your program automatically remembers where it needs to go back to, no matter how deeply functions call more functions.*
When your second function sets the index, what really happens is that the compiler translates the property-set operation into a function call. (Properties are ultimately just "syntactic sugar" for functions.) That function calls a bunch of other functions that aren't important to the scenario, except that one of them is the one that invokes the "index changed" event handler. It sees that you have a method associated with that event, and it calls your first method.
Your first method runs, and when it finishes, it returns to the "invoke the index-changed event handler" function. Eventually, that and all the other unimportant functions finish running (perhaps after making more function calls in sequence), and the "set the index property" function returns control to your second method.
You can prove to yourself that your first suggestion is how it works. Display a message box in your first method, and display another message box after the point in your second method where you set the index property. (Use different messages!) You should see the first message appear, and after you dismiss the message box, you should see the second message appear, thus showing that the second method did not continue executing while the first one was running.
* There is a limit, but it's rarely hit unless there's a bug in your program. When you have too many nested function calls, what happens is a stack overflow.
There's a third alternative you can explore: they can also run at the same time! If I understand your question correctly, method 2 would be triggered by the index change event. In a C# Windows Forms application, this other event would occur in a separate thread of execution.
Concepts to explore: threading.
I hope this gives you a starting point in your explorations of knowledge.
Assuming no multi-thread situation, the event will fire before he end of execution of the method. If you want to see this, code what you have suggested in a .NET language and examine the Il produced. You can do this with ILDASM, or Reflector, or even create your own relfletion application. You do have to understand the syntax of IL enough to see the branch, but it is not that difficult, as long as you understand programming concepts.
Rob has labeled this "syntactical sugar", which I will agree with somewhat. It is really a compiler trick, but I guess it falls under the label "syntactical sugar" as it is commonly used.
I assume the language in question is c# and you thus have a language that supports multiple threads. If you don't want to worry about threads (which would be a bad idea if you consider user experience) you can run your GUI in one thread and have the same behavior, unless the components create their own thread (which would be a bit weird though). If you want to achieve an asynchronous (parallel) execution of the event you need to have the the event triggering in its own thread.
To answer your question: if you aren't using multiple threads, the method triggered by the event will be queued. This is exactly what happens when you see GUI responding slowly in some programs.
Hope it cleared things out and welcome from another newcomer :)
I myself am a beginner, maybe I can help. Method2 would fire, then when the selection changes, Method1 would do his stuff, then Method2 would continue.
If you don't want Method1 to fire at that time, you might want to do is something like:
(REALLY pseudo code)
Method2(object sender, System.EventArgs e)
{
//Unsubscribe Method1 from ListboxEvent
Listbox.OnSelectionChange -= Method1;
... Stuff Method2 actually does ...
Manualy call Method1 if you want it to fire
//Subscribe Method1 from ListboxEvent
Listbox.OnSelectionChange += Method1;
}
It's probably not optimal (and maybe some Best Practices...) but for a lack of a better explanation, at least you have a bit of information to help you search. Hope it helps!