Try-Catch Loop until success - c#

bool hasCopiedArtikelnum = false;
while (hasCopiedArtikelnum == false)
{
try
{
artikelnum = Clipboard.GetText();
hasCopiedArtikelnum = true;
}
catch {}
}
I want the program to keep looping until he has successfully copied. Does putting other things in the "try" work? Or will the programm also >>try<< to set hasCopiedArtikelnum to true?

It seems what you really want to do is wait until the user has copied something to the clipboard and then check whether there is text contained in the clipboard using Clipboard.ContainsText (as already suggested by #CodeCaster and #PatrickHofman).
You can receive clipboard events as described in an answer to this question: Clipboard event C#.
Such an approach is much better because you a) won't be using exceptions for control flow and b) reduce CPU load significantly by avoiding to permanent polling of the clipboard.

The while loop while continue to execute until hasCopiedArtikelnum is true.
This means you can put anything into the try block and it will keep iterating until everything completes, at long as hasCopiedArtikelnum = true is at the end.
If Clipboard.GetText() throws an exception when it's not ready to complete, the execution will jump hasCopiedArtikelnum and it will remain false

Yes, you can catch all exceptions using catch (Exception) {} and it will continue. I advice to use a maximum number of tried though, to prevent this action from hanging.
I guess you are solving a problem with retrieving text. Maybe there are other ways to do so, maybe you can sleep for X milliseconds, use a timer to do it once a X seconds for example, etc. I guess there is another solution you are looking for. This code will hang your process until it succeeds retrieving the text. Are you looking for some event maybe?
Also it is better not to rely on an exception if you can, possibly while (!Clipboard.ContainsText(TextDataFormat.Text)), as CodeCaster suggested it a better solution.

Related

"finally" not executed because of Async in "try"?

I have a bool (b) which appears only twice in my code (besides its declaration):
try
{
b = true;
//code including await SomeAsync();
}
catch { }
finally { b = false; }
yet sometimes the try block is started with b being true (-before b = true) which should never be happening because the declaration leaves it false, as does the previous finally. At some point, this code is executed in a loop, which in some cases is iterating quickly and SomeAsync() is trying to use too much memory. I assume that is throwing an exception of a type that can "break" a finally. (b is always false as expected when there's only a normal amount of data for SomeAsync() to process.)
I've tried verifying what Visual Studio shows me with Debug.WriteLine() both after the try and after the finally, and also by appending to a string a different character in those places, but then the finally was executed. So I assume that the slow delay was enough to prevent the exception.
Is this really possible? (Any ideas on how to verify it or fix it so that the finally always runs?)
(finally blocks can fail - cases: Conditions when finally does not execute in a .net try..finally block )
EDIT
A good point was raised in a comment and an answer - that this code might be executed several times concurrently during the awaits. Unfortunately, there's another detail (that those answers made me aware is pertinent) - after all iterations - the state is that b is true. That is not explained by concurrency. I have also added an if (b) return; before the try block (to avoid calling the Async while the previous is running). Still getting left with a true b after all iterations are done.
This is a pretty common mistake. The code you showed can be run multiple times concurrently. For example, it you attach it to a button click event, the user can click the button ten times in a row, causing ten copies of the function to run at nearly the same time.
In this example they won't literally run at the same time, being ties to the UI thread, but they can overlap with the scheduler jumping from one instance to the next every time it sees an await statement.
If you are running this in the background (e.g. Thread.Start) then each instance will get its own thread and you really will have multiple copies running at the same time.

Exception during lock [duplicate]

In a c# threading app, if I were to lock an object, let us say a queue, and if an exception occurs, will the object stay locked? Here is the pseudo-code:
int ii;
lock(MyQueue)
{
MyClass LclClass = (MyClass)MyQueue.Dequeue();
try
{
ii = int.parse(LclClass.SomeString);
}
catch
{
MessageBox.Show("Error parsing string");
}
}
As I understand it, code after the catch doesn't execute - but I have been wondering if the lock will be freed.
I note that no one has mentioned in their answers to this old question that releasing a lock upon an exception is an incredibly dangerous thing to do. Yes, lock statements in C# have "finally" semantics; when control exits the lock normally or abnormally, the lock is released. You're all talking about this like it is a good thing, but it is a bad thing! The right thing to do if you have a locked region that throws an unhandled exception is to terminate the diseased process immediately before it destroys more user data, not free the lock and keep on going.
Look at it this way: suppose you have a bathroom with a lock on the door and a line of people waiting outside. A bomb in the bathroom goes off, killing the person in there. Your question is "in that situation will the lock be automatically unlocked so the next person can get into the bathroom?" Yes, it will. That is not a good thing. A bomb just went off in there and killed someone! The plumbing is probably destroyed, the house is no longer structurally sound, and there might be another bomb in there. The right thing to do is get everyone out as quickly as possible and demolish the entire house.
I mean, think it through: if you locked a region of code in order to read from a data structure without it being mutated on another thread, and something in that data structure threw an exception, odds are good that it is because the data structure is corrupt. User data is now messed up; you don't want to try to save user data at this point because you are then saving corrupt data. Just terminate the process.
If you locked a region of code in order to perform a mutation without another thread reading the state at the same time, and the mutation throws, then if the data was not corrupt before, it sure is now. Which is exactly the scenario that the lock is supposed to protect against. Now code that is waiting to read that state will immediately be given access to corrupt state, and probably itself crash. Again, the right thing to do is to terminate the process.
No matter how you slice it, an exception inside a lock is bad news. The right question to ask is not "will my lock be cleaned up in the event of an exception?" The right question to ask is "how do I ensure that there is never an exception inside a lock? And if there is, then how do I structure my program so that mutations are rolled back to previous good states?"
First; have you considered TryParse?
in li;
if(int.TryParse(LclClass.SomeString, out li)) {
// li is now assigned
} else {
// input string is dodgy
}
The lock will be released for 2 reasons; first, lock is essentially:
Monitor.Enter(lockObj);
try {
// ...
} finally {
Monitor.Exit(lockObj);
}
Second; you catch and don't re-throw the inner exception, so the lock never actually sees an exception. Of course, you are holding the lock for the duration of a MessageBox, which might be a problem.
So it will be released in all but the most fatal catastrophic unrecoverable exceptions.
yes, that will release properly; lock acts as try/finally, with the Monitor.Exit(myLock) in the finally, so no matter how you exit it will be released. As a side-note, catch(... e) {throw e;} is best avoided, as that damages the stack-trace on e; it is better not to catch it at all, or alternatively: use throw; rather than throw e; which does a re-throw.
If you really want to know, a lock in C#4 / .NET 4 is:
{
bool haveLock = false;
try {
Monitor.Enter(myLock, ref haveLock);
} finally {
if(haveLock) Monitor.Exit(myLock);
}
}
"A lock statement is compiled to a call to Monitor.Enter, and then a try…finally block. In the finally block, Monitor.Exit is called.
The JIT code generation for both x86 and x64 ensures that a thread abort cannot occur between a Monitor.Enter call and a try block that immediately follows it."
Taken from:
This site
Just to add a little to Marc's excellent answer.
Situations like this are the very reason for the existence of the lock keyword. It helps developers make sure the lock is released in the finally block.
If you're forced to use Monitor.Enter/Exit e.g. to support a timeout, you must make sure to place the call to Monitor.Exit in the finally block to ensure proper release of the lock in case of an exception.
Your lock will be released properly. A lock acts like this:
try {
Monitor.Enter(myLock);
// ...
} finally {
Monitor.Exit(myLock);
}
And finally blocks are guaranteed to execute, no matter how you leave the try block.

correct way to handle exit from infinite loop in c#

In my apps i find the need to have infinite while loops mostly to do some repeated action continuosly unless another event takes place so what i am doing is
while(chkFlag)
{
//do something here which takes around 30 seconds
}
Then in some other event say a button press to stop the loop i do
chkFlag = false;
Now this does the work but the problem is this does not stop the loop instantaneously as the chkFlag is checked only after the complete execution of the loop takes place. So can anybody please tell me how i can exit a loop instantaneouly based on an event.
The "blocking" code should likely be moved into some kind of worker thread (which can be terminated and/or have the results discarded). If using a BackgroundWorker (recommended, as it makes this simple), there is built-in support to handle a cancel operation.
Then the loop can either be moved inside the BackgroundWorker or the completion (RunWorkerCompleted) event of the worker can trigger the next worker to start (which causes an implicit loop).
Happy coding.
There are more "aggressive" ways of terminating/signaling a thread; but suggesting these would require more information than present.
you can't make it exit instantly (well, you could run the loop in a new thread and Abort it, if it's really safe to have an exception thrown from it at any time), but you could scatter if(!chkFlag) break; at various points within the loop that it's safe to exit. The usual method of doing this is to use a BackgroundWorker or a CancellationToken rather than a simple boolean flag.
Of course, it will still need to be run in another thread so that the button event can run at all. BackgroundWorker will take care of this automatically.
You are looking for break;.
I suppose, based on the anonymous downvoter, I should elaborate. The syntax above will immediately exit the loop that you are in (it works in the other loops as well; it's probably worth noting that continue exists to restart the loop at the beginning, which will perform increment logic in for-style loops).
How you decide to execute break is up to you, but it must be within the loop itself.
There are multiple approaches to this, such as placing checks for the event within the loop and calling break; if it occurs. Others have noted the other approaches with BackgroundWorkers and Cancel Tokens (this is preferred given it's not within the loop).
Is it possible you want to use a new thread? What are you doing for 30 seconds in the loop. Sounds like maybe there's a better design to use.
Have you considered using a timer, or setting up an event handler?

locking a resource via lock within try. Is it wrong?

Is there anything wrong with using lock with a try block? I remember reading somewhere that we should always try to put minimum amount of code within try block and lock itself internally uses a try-finally block, do you guys see something wrong here.I need to deal with the fact that the code within that lock block can throw exception
try
{
lock(syncblk)
{
// do some processing
}
}
catch(Exception e)
{
// do something with exception
}
I need to deal with the fact that the code within that lock block can throw exception
And there's your problem. That's a terrible situation to be in.
Why are you locking in the first place? Usually the reason why you lock something is because you want to implement the following logic:
lock the door
make a mess
clean it up
unlock the door
If you do that, then no one who honours the locked door ever sees the mess.
For example, you might want to swap values of variables "left" and "right" in a threadsafe manner, so you:
take the lock
read the left variable into tempLeft
read the right variable into tempRight
write tempLeft into right
we just made a mess; the original value of 'right' has gone missing
write tempRight into left
we've cleaned up the mess, all is well with the world again
release the lock
Now suppose an exception is thrown after the mess is made. What happens? We jump straight to the unlock, leaving the mess for another thread to see.
That's why you should never throw an exception inside a lock; it completely defeats the purpose of the lock! The whole point of a lock is to ensure that state is always observed to be consistent by all threads except the one responsible for cleaning up the mess.
If you have an exception that can be thrown from inside a lock, the best thing to do is to get out of that horrible situation. If you can't do that, then make sure that you can either (1) destroy the process utterly as soon as the exception escapes the lock, so that the mess you made cannot cause data loss or other harm -- do a FailFast and nuke the process from orbit, it's the only way to be sure -- or (2) write rollback code that undoes whatever operation you were attempting before the lock is exited; that is, clean up the mess back to the original state.
If the latter is your strategy then don't put the try block outside the lock; it's useless there because the instant control leaves the lock via the exception another thread can be crashing and dying because of the mess you left exposed to it. Put the try that deals with the exception inside the lock:
lock(whatever)
{
try
{
MakeAMess();
}
finally
{
CleanItUp();
// Either by completing the operation or rolling it back
// to the pre-mess state
}
}
If you have strong reliability requirements then dealing with locked critical sections which can throw exceptions is an extremely difficult programming task best left to experts; you might consider using a constrained execution region if you find yourself in this situation a lot.
I think you can do it your way but here is the MSDN description on lock for your information. Please refer to http://msdn.microsoft.com/en-us/library/ms173179.aspx for more info.
Using the lock (C#) or SyncLock
(Visual Basic) keyword is generally
preferred over using the Monitor class
directly, both because lock or
SyncLock is more concise, and because
lock or SyncLock insures that the
underlying monitor is released, even
if the protected code throws an
exception. This is accomplished with
the finally keyword, which executes
its associated code block regardless
of whether an exception is thrown.
So I am not sure what kind of exception you are referring to but if you concern is that you may not be able to release the lock because of exception, you do not have to worry about it.
you can always use the longer syntax like this:
System.Threading.Monitor.Enter(x);
try {
...
}
catch(Exception e)
{
}
finally {
System.Threading.Monitor.Exit(x);
}

Game design - main loop aborting - Is there a better way than Abort() and ResetAbort()?

I have a C# threading program (a game), that stops with a boolean (as most articles recommend).
while (gameContinueRun)
{
createRound();
line1;
line2;
line3;
line4;
endRound();
}
Some code lines lock the game and wait until other thread will release it:
lock (stateSync)
{
Monitor.Wait(stateSync)
}
To stop the thread from another thread I set the boolean to false:
if (cancel)
{
gameContinueRun= false;
}
Everything works nicely, but I still need to wait until the end of the current loop (round).
I want to end the loop, to break all work in the middle (abort game). Another thing is to be able to restart the loop (open new round). Or in other words, two things:
abort the game
cancel the current round and start a new one
I thought about it, and got a couple of ways:
Unlock all locks, and check after every code line:
if (!cancelRound)
{
line1;
}
if (!cancelRound)
{
line2;
}
if (!cancelRound)
{
line3;
}
if (!cancelRound)
{
line4;
}
Not very nice, and very exhausting if one have lots of code lines to cover...
Use Thread.Abort(), catching the Exception and resetAbort() if needed.
Use goto and labels (which I assume is even uglier then aborting).
Which way is better? Or moreover, is there a better recommended way?
Try looking at WaitHandle.WaitAny(WaitHandle[]) method for your locks.
Then you can work with arrays of AutoResetEvent or ManualResetEvent - one for exiting and all the rest for the locking.
See:
http://msdn.microsoft.com/en-us/library/yy12yx1f.aspx
I usually end up writing lots of
if (m_state != GameState.Active) {
return;
} // if
kind of code.
Maybe you could use custom attribute, similar to that of code access security. And do something like
[RequireState(GameState.Active)]
void DoSomething();
It not entirely clear what you are trying to do, but it looks like you want some form of inter-thread communication. However, it is usual for the game loop to control the other threads, not to be controlled itself. So instead you'd have:
function GameLoop
start threads
while (continuing game loop)
tell threads to do something
wait for threads to finish doing something
end while
tell threads to stop
wait for threads to terminate
end function
Your solution using the lock and Monitor.Wait is unusual and probably not robust enough. I think you need to do some research into multi-threading and maybe tryout some classical problems (the dining philosophers for example) and then redesign your code.

Categories

Resources