How to set value of variable in "BeginInvoke" delegate function in C#? - c#

I have this code on different thread:
string sub = "";
this.BeginInvoke((Action)(delegate()
{
try
{
sub = LISTVIEW.Items[x].Text.Trim();
}
catch
{
}
}));
MessageBox.Show(sub);
what I want is to get the value of "LISTVIEW.Items[x].Text.Trim();" and pass it to "sub". please note that the LISTVIEW control is on the main thread. now how can I accomplish this?
enter code here

Func<string> foo = () =>
{
try
{
return LISTVIEW.Items[x].Text.Trim();
}
catch
{
// this is the diaper anti-pattern... fix it by adding logging and/or making the code in the try block not throw
return String.Empty;
}
};
var ar = this.BeginInvoke(foo);
string sub = (string)this.EndInvoke(ar);
You, of course, need to be a bit careful with EndInvoke because it can cause deadlocks.
if you prefer delegate syntax you can also change
this.BeginInvoke((Action)(delegate()
to
this.BeginInvoke((Func<String>)(delegate()
you stll need to return something from all branches and call end invoke.

Related

Is there a more efficient syntax for mutliple try/catch?

I have a callback web method that Facebook is calling. Unfortunately, the purpose of the call using this single url is determined solely by the structure of the object (json) that is passed in the Post body. Right now, I am thinking of:
try { Class1 obj1 = JsonConvert.DeserializeObject<Class1>(rawData);
//code to run if data is of Class1 ...
}
catch
{ try { Class2 obj2 = JsonConvert.DeserializeObject<Class2>(rawData);
//code to run if data is of Class2 ...
}
catch
{ Class3 obj3 = JsonConvert.DeserializeObject<Class3>(rawData);
//code to run if data is of Class3...
}
}
Is there a cleaner better way than the above?
Ideally, you shouldn't use exceptions to drive decisions on code paths that do not deal with exceptional situations. If this is something that you cannot avoid, you could set up a loop that tries different classes, like this:
var deserializers = new Func<string,object>[] {
(rawData) => JsonConvert.DeserializeObject<Class1>(rawData)
, (rawData) => JsonConvert.DeserializeObject<Class2>(rawData)
, (rawData) => JsonConvert.DeserializeObject<Class3>(rawData)
};
object result = null;
foreach (var d in deserializers) {
try {
result = d(rawData);
break;
} catch {
// Conversion was unsuccessful
}
}
If deserializing went OK, break statement is reached, and your loop exits. Otherwise, the loop continues to the next iteration, until the loop succeeds, or we run out of deserializers.
Note: An explicit cast may be required in order to put functors into an array:
(rawData) => (object)JsonConvert.DeserializeObject<Class1>(rawData)

Try-catch until success - execution loop for generic methods or delegates

I want my code to keep trying a method until no exception is thrown, however, unlike this question, I would like it to be written as a generic method capable of running any input delegate/method. Here is what I've had in mind, but I am not sure how to pass the arguments or generic methods through it:
public void tryLoop(Delegate anyMethod, T[] arguments) {
while (true) {
// Could be replaced by timer timeout
try {
anyMethod(arguments);
break;
}
catch {
System.Threading.Thread.Sleep(2000); // wait 2 seconds
}
}
}
Is this possible?
EDIT: For the academics of it, I would also be curious to know if it's possible to return the result as well.
If you can settle for using closures, you won't need to have to pass parameters to this method all (or have multiple overloads). The result can be returned using a Func.
public T tryLoop<T>(Func<T> anyMethod)
{
while (true)
{
try
{
return anyMethod();
}
catch
{
System.Threading.Thread.Sleep(2000); // *
}
}
return default(T);
}
void SomeMethod(int param)
{
var someLocal = "Hi";
var anotherLocal = 0;
var result = tryLoop(() =>
{
Console.WriteLine(someLocal);
return param + anotherLocal;
});
Console.Write(result);
}
To be honest, I wouldn't set an infinite retry, however - at best, if certain types of retryable error were returned, such as a database deadlock, or a timeout calling an erratic web service, then possibly 3 or 4 retries might be in order. Exceptions such DivideByZero or FileNotFound aren't likely to go away by running them indefinitely :-)
*** especially with deadlocks, sleeping for a random period is recommended, just in case other threads are also simultaneously deadlocking on exactly the same data - you don't want the same deadlock recurrence happening in 2000ms :-).
A way to do this is by using an Action, and remove the arguments parameter:
public void tryLoop(Action anyMethod) {
while ( true ) {
// Could be replaced by timer timeout
try {
anyMethod();
break;
}
catch {
System.Threading.Thread.Sleep(2000); // wait 2 seconds
}
}
}
This gives you ultimate freedom in how to use it:
tryLoop(() => string.Reverse("abc"));
or like this:
String s1 = "A";
String s2 = "b";
tryLoop(() => string.Concat(s1, s2));
As you can see in the second example, you can directly take the arguments from the context of the tryLoop method being called. You can invoke anything there.
The good thing for this approach is that you will not have to use Invoke or DynamicInvoke as with a Delegate instead of Action, because these introduce a performance penalty.
If you need the result, you can re-write the above with a Func<T> instead of Action, like this:
public T tryLoop<T>(Func<T> anyMethod) {
while ( true ) {
// Could be replaced by timer timeout
try {
return anyMethod();
}
catch {
System.Threading.Thread.Sleep(2000); // wait 2 seconds
}
}
}
and use it like this:
var reversed = tryLoop(() => string.Reverse("abc"));
String s1 = "A";
String s2 = "b";
var concatenated = tryLoop(() => string.Concat(s1, s2));
Check if this suit your needs. If not then please comment. Also not sure how it will be performance wise.
Also the DynamicInvoke method has an object return type. This you can use to return the result of the delegate. You can change the return type of method from void to object.
public void tryLoop<T>(Delegate anyMethod, T[] arguments)
{
while (true)
{ // Could be replaced by timer timeout
try
{
anyMethod.DynamicInvoke(arguments);
break;
}
catch
{
System.Threading.Thread.Sleep(2000); // wait 2 seconds
}
}
}
Hope this helps

Implicitly-Typed Variables in try...catch

I like using implicit typing for almost everything because it's clean and simple. However, when I need to wrap a try...catch block around a single statement, I have to break the implicit typing in order to ensure the variable has a defined value. Here's a contrived hypothetical example:
var s = "abc";
// I want to avoid explicit typing here
IQueryable<ABC> result = null;
try {
result = GetData();
} catch (Exception ex) { }
if (result != null)
return result.Single().MyProperty;
else
return 0;
Is there a way I can call GetData() with exception handling, but without having to explicitly define the type of the result variable? Something like GetData().NullOnException()?
This is a common problem. I recommend that you just stick with your existing solution.
If you really want an alternative, here it is:
static T NullOnException<T>(Func<T> producer) where T : class {
try { return producer(); } catch { return null; } //please modify the catch!
}
//now call it
var result = NullOnException(() => GetData());
Please modify this to log the exception or restrict the catch to a concrete type. I do not endorse swallowing all exceptions.
As this answer is being read a lot I want to point out that this implementation is just of demo-quality. In production code you probably should incorporate the suggestions given in the comments. Write yourself a robust, well-designed helper function that will serve you well for years.
Just put your code inside the try:
var s = "abc";
// I want to avoid explicit typing here
try {
var result = GetData();
if (result != null)
return result.Single().MyProperty;
else
return 0;
} catch (Exception ex) { }
I came to a similar solution as #usr, but with slightly different semantics:
T LiftScope<T>(Func<T> ScopedFunction)
{
T result = ScopedFunction();
return result;
}
The purpose of LiftScope is to carry an internal variable out to the caller without compromising implicit typing. This could be used to solve the original problem, except that the try...catch would actually be embedded in the call.
try...catch
var result =
LiftScope(() => {
try { return producer(); } catch { return null; }
});
Now the caller is able to be responsible for exception handling. Furthermore, this can be used generically in a handful of similar use-cases where you have very short-lived scopes.
if
var result =
LiftScope(() => {
if (a == b)
return GetData(true);
else if (b == c)
return GetData(false);
else
return GetData(true, 2);
});
This could also be solved with a ternary-style if statement.
using
var result =
LiftScope(() => {
using (var myContext = new MyDataContext())
{
return myContext.MyTable.Where(w => w.A == B).ToList();
}
});

How to refactor code with try-catch-finally

I have to create a bunch of methods that look like this. The things that change will be the method name, the return type and the lines marked in the middle - the rest will be the same. Is there a clean way to refactor this so that I don't repeat myself?
private bool CanPerform(WindowsIdentity identity, string applicationName, int operation)
{
IAzApplication3 application = null;
IAzClientContext3 context = null;
try
{
application = this.store.OpenApplication(applicationName, null) as IAzApplication3;
ulong token = (ulong)identity.Token.ToInt64();
context = application.InitializeClientContextFromToken(token, null) as IAzClientContext3;
// lines that change go here
}
catch (COMException e)
{
throw new SecurityException(string.Format("Unable to check operation '{0}'", operation), e);
}
finally
{
Marshal.FinalReleaseComObject(context);
Marshal.FinalReleaseComObject(application);
}
}
I realise this is probably basic stuff but I work alone so there's no one else to ask.
It sounds like a delegate would be appropriate here, with a generic method to cover the return type changing:
private T ExecuteWithIdentity<T>(WindowsIdentity identity,
string applicationName, int operation,
Func<IAzApplication3, IAzClientContext3, T> action)
{
IAzApplication3 application = null;
IAzClientContext3 context = null;
try
{
application = this.store.OpenApplication(applicationName, null) as IAzApplication3;
ulong token = (ulong)identity.Token.ToInt64();
context = application.InitializeClientContextFromToken(token, null) as IAzClientContext3;
return action(application, context);
}
catch (COMException e)
{
throw new SecurityException(
string.Format("Unable to check operation '{0}'", operation), e);
}
finally
{
Marshal.FinalReleaseComObject(context);
Marshal.FinalReleaseComObject(application);
}
}
Then you put the code for each check in a separate method, or even just use a lambda expression:
bool check = ExecuteWithIdentity(identity, "Foo", 10,
(application, context) => context != null);
or
string check = ExecuteWithIdentity(identity, "Foo", 10, SomeComplexAction);
...
private static string SomeComplexAction(IAzApplication3 application,
IAzClientContext3 context)
{
// Do complex checks here, returning whether the user is allowed to
// perform the operation
}
You may want to change the delegate type of course - it's not clear what operation is meant to be used for, for example.
I would also strongly consider casting instead of using as. If the application or context is returned from OpenApplication/InitializeClientContextFromTokenas a non-null value which just isn't the right type, do you really want to handle that the same was as a null value being returned?
You could do your error handling slightly higher up the stack, so rather than catching and rethrowing the exception inside the method you could do it where the method is called?
If your method calls are all wrapped in a Manager class that might save a bit of time. If they're just ad-hoc called everywhere then naturally maybe not :)
I hope that might help.

How to explicitly pass a program flow into the finally block in C#?

In Delphi I could do something like this:
try
if not DoSomething then
Exit;
if not DoSomething2 then
Exit;
if not DoSomething3 then
Exit;
finally
DoSomethingElse;
end;
In other means if method DoSomething results false then the program flow is transffered to the finally block and DoSomething2 and DoSomething3 are not executed.
How to achieve such behaviour in C#?
Thanks in advance.
Edit1:
The below example doesn't compile in VS 2008
Edit2: I am sorry I was to fast and forget the return statement;
XElement OrderStatus(q_order_status Request)
{
XElement Response;
try
{
if (DoSomething() != 0 )
{
return;
}
}
catch(Exception e)
{
// catch some errors and eventually pass the e.Message to the Response
}
finally
{
Response = new XElement("SomeTag", "SomeResponse");
}
return Response;
}
Edit3:
After testing it seems that the easiest way to achieve this is to throw an exception if the result of DoSomething1 is false. I can throw my own execption, write a specific message and pass it to the finally clause.
You really shouldn't be using exception handling constructs for flow control. That said, Exit is comparable to return in C#. As the MSDN Documentation about the [return keyword][1] says:
If the return statement is inside a try block, the finally block, if one exists, will be executed before control returns to the calling method.
In general a finally-block will almost always execute if the corresponding try-block has been reached. There are a few rare situations where it is impossible to guarantee that the finally-block executes, but they are all fatal errors, upon which programs should likely immediately crash.
How your code would look in C#:
try
{
if (!DoSomething())
return;
if (!DoSomething2())
return;
if (!DoSomething3())
return;
}
finally
{
DoSomethingElse();
}
But again, don't do this. try and finally are intended for handling exceptions, not for normal flow control.
Reply to your edit:
In your code return doesn't compile because the return type of the method is XElement and return by itself can only be used when the return type is void. You could use return new XElement("SomeTag", "SomeResponse");, as that is what the finally would be doing anyway, or you could assign Response earlier and do return Response;.
Note though that while the finally always executes, the return Response; that comes after it doesn't execute if the reason went into the finally-block is because you did a return inside the try-block.
Answer to updated question:
The reason you're having trouble doing this in an elegant way, is because you seem to be using a combination of return values and exceptions. You should consider manually raising an exception instead of using return values if the sitation is, well, exceptional.
Assuming there is a good reason for the return values however, I'm thinking it might be clearer to go without a finally block altogether, and to include a return at the end of the try block and also in your catch block. That would save you from passing the exception message in a messy way.
I can't really say what the best solution would be, since your code snippet does not show what Response would be if DoSomething() returns a non-zero value.
Original answer:
It depends a little on what you're trying to accomplish. Are exceptions actually being thrown in any of the methods? Otherwise there is no good reason to use a try-finally pattern. This would be equivalent (though maybe not advisable for readability):
bool doneEverything = DoSomething() && DoSomething2() && DoSomething3();
DoSomethingElse();
If there are exceptions being thrown, and handled at a higher level, I'd recommend isolating this code in a separate method, so you can use a return statement*.
void DoStuff()
{
try
{
if (!DoSomething())
return;
if (!DoSomething2())
return;
if (!DoSomething3())
return;
}
finally
{
DoSomethingElse();
}
}
To answer your question about when the finally code block is executed: it is always executed, unless the executing thread terminates prematurely.
*: Some restructuring is recommended, because there is no equivalent of the Delphi Exit. The break statement comes closest, but it can only be used in loop constructs or switch blocks. To mimic Exit behavior, you would need goto and a label. We wouldn't want that, now would we? :)
Why not make the three try-lines a common if/else block? Instead of exit, call the DoSomethingElse. Like so:
if (DoSomething() == false)
{
DoSomethingElse();
}
else if (DoSomething2() == false)
{
DoSomethingElse();
}
else if (DoSomething3() == false)
{
DoSomethingElse();
}
I would like to say that "C# is not Delphi", but that would be a bit arrogant.
In C#, finally is executed as well when return is called inside the try statement.
bool doSomething = false;
bool doSomething2 = true;
try
{
if( !doSomething )
{
Console.WriteLine ("not dosomething");
return;
}
if( !doSomething2 )
{
Console.WriteLine ("not dosomething 2");
return;
}
}
finally
{
Console.WriteLine ("In finally");
}
What about switch case of course If you don't mean the finally in c# by saying finally block. default case is the finally block then and you can also find flow control example and here at msdn : Flow Control (C# vs. Java)
static void Main(string[] args)
{
switch (args[0])
{
case "copy":
//...
break;
case "move":
//...
goto case "delete";
case "del":
case "remove":
case "delete":
//...
break;
default:
//...
break;
}
}
In this sort of situation, understanding the question as dealing exclusively with the non-exception handling case, I would refactor the contents of the try into a private helper method, like this
void BranchOnContext()
{
if (!DoSomething())
return;
if (!DoSomething2())
return;
// last one will drop out and return anyway
DoSomething3();
}
void DoStuff()
{
BranchOnContext(); // Assumed not to throw
DoSomethingElse(); // Always the next thing to be executed
}
EDIT -- tracking the changed requirement
void DoStuff()
{
string message = string.Empty;
try {
BranchOnContext();
} catch (MyExpectedException me) { // only catch exceptions I'm prepared to handle
message = me.Message;
}
DoSomethingElse(message); // Always the next thing to be executed
}
Taking another crack at this with the updated info:
I want DoSomethingElse to be executed
always and I want it to include
message from possible exception
If any of the DoSomething's return 0, null is returned. If not, the generic message is created. If there was an exception, it is caught and a message with its info is returned. How about this?
XElement OrderStatus(q_order_status Request)
{
try
{
if (DoSomething() != 0 )
{
return null;
}
else
{
return new XElement("SomeTag", "SomeResponse");
}
}
catch(Exception e)
{
// catch some errors and eventually pass the e.Message to the Response
return new XElement(e.tag, e.response);
}
}
Im still struggling with how to, in a good way, put finally into this.
I find it quite similar in behavior to the Delphi's one which I have shown on the beginning. I am interested in your comments. Response is dependent on the DoSomethings result.
XElement OrderStatus(q_order_status Request)
{
XElement Response;
int result = 0;
string Message = "";
try
{
result = DoSomething1();
if (result != 0)
{
throw new DoSomethingException("DoSomething1 has failed!");
}
result = DoSomething2();
if (result != 0)
{
throw new DoSomethingException("DoSomething2 has failed!");
}
result = DoSomething3();
if (result != 0)
{
throw new DoSomethingException("DoSomething3 has failed!");
}
Message = "All tests has been passed.";
}
catch(DoSomethingException e)
{
Message = e.Message;
}
catch(Exception e)
{
Message = e.Message;
}
finally
{
Response = new XElement("SomeTag", Message);
}
return Response;
}
What do you think?
void funcA()
{
if (!DoSomething())
return;
if (!DoSomething2())
return;
if (!DoSomething3())
return;
}
void funcB()
{
funcA();
DoSomethingElse;
}
This appears to replicate the delphi:-
try
{
if(DoSomething())
if(DoSomething2())
DoSomething3();
}
finally
{
DoSomethingElse();
}
an alternate style (some people will hate this style, others will love it.):-
try
{
DoSomething() && DoSomething2() && DoSomething3();
}
finally
{
DoSomethingElse();
}
I get the impression you want some other behaviour though?
Goto version?
try
{
if (!DoSomething())
goto Exit;
if (!DoSomething2())
goto Exit;
if (!DoSomething3())
goto Exit;
Exit:;
}
finally
{
DoSomethingElse();
}
Note the irritating ; after the label, it seems a label must precede a statement.
Just had an epiphany:-
Func<bool>[] somethings = new Func<bool>[] {DoSomething, DoSomething2, DoSomething3};
try
{
foreach (Func<bool> something in somethings)
{
if (!something())
break;
}
}
finally
{
DoSomethingElse();
}

Categories

Resources