I am relatively new to C#, maybe you could help me with this.
I got a couple of methods callServiceXY(param1, param2, ...) that call a certain service. For many reasons these service calls can go wrong (and I don't really care for the reason in the end). So basically I need to always wrap them with something like this - to have them execute again if something goes wrong:
var i = 3;
while(i>0)
try{
call...()
} catch{
i--;
}
i=0;
}
I'd rather write this code only once. Could I somehow have a method like tryXtimes(int x, callService()) that allows me to execute an undefined or anonymous method? (I have Javascript in mind where this is possible...)?
Yes this is possible. C# 3.5 added support for Action and Func<T> types. An Action won't return any value, a Func will always return a value.
You have several different versions that also accept a number of parameters. The following Console Applications describes how you could do this:
using System;
namespace Stackoverflow
{
class Service
{
public int MyMethod() { return 42; }
public void MyMethod(string param1, bool param2) { }
public int MyMethod(object paramY) { return 42; }
}
class Program
{
static void ExecuteWithRetry(Action action)
{
try
{
action();
}
catch
{
action();
}
}
static T ExecuteWithRetry<T>(Func<T> function)
{
try
{
return function();
}
catch
{
return function();
}
}
static void Main(string[] args)
{
Service s = new Service();
ExecuteWithRetry(() => s.MyMethod("a", true));
int a = ExecuteWithRetry(() => s.MyMethod(1));
int b = ExecuteWithRetry(() => s.MyMethod(true));
}
}
}
As you can see, there are two overloads for ExecuteWithRetry. One returning void, one returning a type. You can call ExecuteWithRetry by passing an Action or a Func.
--> Edit: Awesome! Just a little extra code to complete the example:
With anonymous function/method:
ExecuteWithRetry(() =>
{
logger.Debug("test");
});
And with more parameters (action, int)
Method header:
public static void ExecuteWithRetryX(Action a, int x)
Method call:
ExecuteWithRetryX(() => { logger.Debug("test"); }, 2);
I would use the strategy/factory pattern(s) for this. This answer https://stackoverflow.com/a/13641801/626442 gives and example of the use of the strategy/factory pattern with links. The question at the above link will give you another type of example where this pattern can be adopted.
There are great examples of these design patterns here and the following are detailed intros to the Strategy pattern and the Factory pattern. The former of the last two links also shows you how to combine the two to do something like what you require.
I hope this helps.
Try following
void CallServiceXY(params object []objects)
{
Console.WriteLine("a");
throw new Exception("");
}
void Retry(int maxRetryCount, Action<object[]> action, params object[] obj)
{
int retryCount = 1;
while ( retryCount <= maxRetryCount)
{
try
{
action(obj);
return;
}
catch
{
retryCount++;
}
}
}
void Main()
{
Retry(2,CallServiceXY);
Retry(2,CallServiceXY,"");
Retry(2,CallServiceXY,"","");
}
Demo here
Trick is Action<object[]> that accepts object array and return void and params keyword in Retry method.
To return non void value, Change Action<object[]> to Func<T, object[]>.
Related
What if I have classes that are different only by some constant used in code. Is it possible to have one generic implementation without runtime cost?
Here is the example (it's a little bit too long...)
#:enum abstract Param(Int) {
var foo = 0;
var bar = 1;
}
class WorkBase {
public function new() {}
private inline function work_impl(p: Param): Void {
if(p == foo) {
trace('foo');
}
else {
trace('bar');
}
}
public function work(): Void {
}
}
class WorkFoo extends WorkBase{
override public function work(): Void {
work_impl(foo);
}
}
class WorkBar extends WorkBase {
override public function work(): Void {
work_impl(bar);
}
}
class Test {
public static function main() {
var workFoo = new WorkFoo();
var workBar = new WorkBar();
workFoo.work();
workBar.work();
}
}
After compilation with -D analyzer-optimize we will see that WorkFoo.work() and WorkBar.work() functions were optimized and contain only one branch of code that matches one of the Param values. In real life there are lot of such comparisons in work_impl(), and they all are optimized out. That's good.
But what if I do not want to create WorkFoo and WorkBar by hand. Is it possible to do something like this:
#:generic
class WorkBase<PARAM> {
private inline function work_impl(p: Param): Void {
...
}
public function work(): Void {
work_impl(PARAM);
}
}
The closest thing I know is const-type-parameter. But I do not feel generic build is a good choice here.
The closest thing I know is const-type-parameter. But I do not feel generic build is a good choice here.
Const type parameters can be used without #:genericBuild - a const type parameter in combination with #:generic is enough to get the desired optimization:
#:enum abstract Param(Int) from Int {
var foo = 0;
var bar = 1;
}
#:generic class Work<#:const PARAM:Int> {
public function new() {}
public function work():Void {
if (PARAM == foo) {
trace('foo');
} else {
trace('bar');
}
}
}
class Main {
public static function main() {
var workFoo = new Work<0>();
var workBar = new Work<1>();
workFoo.work();
workBar.work();
}
}
Due to #:generic, one class is generated for each constant value, for instance on JS the output looks like this:
var Work_$0 = function() {
};
Work_$0.prototype = {
work: function() {
console.log("source/Main.hx:11:","foo");
}
};
var Work_$1 = function() {
};
Work_$1.prototype = {
work: function() {
console.log("source/Main.hx:13:","bar");
}
};
Note that this example fails with a "constraint check failure" in Haxe 3.4.7 for some reason, but works fine with Haxe 4 preview 4 and later. Another limitation is that neither new Work<Param.foo>() nor new Work<foo>() work - you need to pass the actual constant value.
I'm trying to write a Jenkins Job DSL script and would like to write it as declaratively / DRY-ly as possible. The Jenkins task is calling some other tasks via a MultiJob. I have Groovy that originally looks like this (everything's contained within a class because it's referenced elsewhere):
static void buildDownstream(def parentJob, String commit_a="master",
String commit_b="master") {
parentJob.with {
steps {
phase('Phase') {
job("name_1") {
prop('COMMIT_A', commit_a)
nodeLabel('NODE_LABEL', NODE_LABEL_MAP["name_1"])
killPhaseCondition('NEVER')
}
job("name_2") {
prop('COMMIT_A', commit_a)
prop('COMMIT_B', commit_b)
nodeLabel('NODE_LABEL', NODE_LABEL_MAP["name_2"])
killPhaseCondition('NEVER')
}
job("name_3") {
prop('COMMIT_A', commit_a)
prop('COMMIT_B', commit_b)
nodeLabel('NODE_LABEL', NODE_LABEL_MAP["name_3"])
killPhaseCondition('NEVER')
}
}
}
}
}
I'd like to abstract out the job creation, which contains lots of duplication. I've ended up with something strange like this:
static void buildDownstream(def parentJob, String commit_a="master",
String commit_b="master") {
parentJob.with {
steps {
phase('Phase') {
def phase = ({ owner })();
{ ->
add_node_label=true;
{ ->
commit_a = null;
def self = ({ owner })();
addJob("name_1", self).call(phase);
}
def self = ({ owner })();
addJob("name_2", self).call(phase);
addJob("name_3", self).call(phase);
}
}
}
}
}
private static Closure addJob(String job_name, Closure callingClosure) {
return { phase ->
def job_config = {
if(commit_a != null) {
prop('COMMIT_A', commit_a)
}
if(commit_b != null) {
prop('COMMIT_B', commit_b)
}
if(add_node_label == true) {
nodeLabel('NODE_LABEL', NODE_LABEL_MAP[job_name])
}
killPhaseCondition('NEVER')
}
job_config.delegate = callingClosure
job_config.resolveStrategy = Closure.DELEGATE_ONLY
phase.job(job_name, job_config)
}
}
which, probably being totally non-idiomatic Groovy (all this def self = ({ owner })() stuff doesn't sit right with me), doesn't work at all.
Basically, I want to pass all the variables in callingClosure's scope to the job_config closure without explicitly passing all of them in as arguments. (Explicitly passing a map of arguments works, but it gets unwieldy when there are lots of arguments.) How can I do this?
(P.S: Currently, Groovy is trying to resolve the commit_a variable inside job_config as coming from javaposse.jobdsl.dsl.helpers.step.PhaseContext, which I find strange; didn't I explicitly set the delegate to a closure inside that PhaseContext?)
EDIT: From another SO question, it appears that I can set phase = delegate (which defaults to owner?) instead of ({ owner })() and be fine; I don't really get this either, since job is a property of the PhaseContext, and not its parent (?)
Well, I ended up not trying to ask Groovy to implicitly resolve variables from the delegate context, and instead just passed in the parameters in a map.
static void buildDownstream(def parentJob,
String commit_a="master", String commit_b="master") {
parentJob.with {
steps {
phase('Tests') {
def params = [COMMIT_A:commit_a]
this.getTestJob(delegate, "name_1", params)
params.COMMIT_B = commit_b
this.getTestJob(delegate, "name_2", params)
this.getTestJob(delegate, "name_3", params)
continuationCondition('ALWAYS')
}
}
}
}
private static void getTestJob(def phase, String job_name,
Map properties) {
phase.job(job_name) {
properties.each { k, v -> prop(k, v) }
killPhaseCondition('NEVER')
}
}
One problem with my original method was that I was trying to access local variables in the closures, but that requires the closure to be evaluated; that turns out to be really weird, and I guess I should just not try to do that.
I have the following class:
class WidgetClient {
List<Widget> getAllWidgets() {
_actuallyGetAllWidgets()
}
void saveWidget(Widget w) {
_actuallySaveWidget(w)
}
void deleteWidget(Widget w) {
_actaullyDeleteWidget(w)
}
}
This class is a client access class for a Widget Service. Unfortunately the Widget Service is not very reliable and, for reasons I can't explain, without any sort of reproducibility, is intermittently unavailable. Any time my code executes one of the WidgetClient methods (hence invoking the remote Widget Service), I would like to retry up to 5 times if the invocation produces a WidgetServiceMethodUnavailableException. Now I could do this the non-Groovy way like so:
List<Widget> getAllWidgets() {
int maxRetries = 5
int currRetries = 0
while(currRetries <= maxRetries) {
currRetries++
try {
return _actuallyGetAllWidgets()
} catch(WidgetServiceMethodUnavailableException wsmuExc) {
continue
} catch(Throwable t) {
throw t
}
}
}
But that is nasty and worse yet, I need to add that code for each method inside the WidgetClient. I'd like to see if I could define a closure where this retry logic is stored, and then somehow invoke that closure from inside each WidgetClient method. Something like:
def faultTolerant = { Closure<T> method ->
int maxRetries = 5
int currRetries = 0
while(currRetries <= maxRetries) {
currRetries++
try {
return method()
} catch(WidgetServiceMethodUnavailableException wsmuExc) {
continue
} catch(Throwable t) {
throw t
}
}
}
Now my WidgetClient can look like:
class WidgetClient {
List<Widget> getAllWidgets() {
faultTolerant(_actuallyGetAllWidgets())
}
void saveWidget(Widget w) {
faultTolerant(_actuallySaveWidget(w))
}
void deleteWidget(Widget w) {
faultTolerant(_actaullyDeleteWidget(w))
}
}
However, having never written my own Groovy closure before, I have no idea where to start. Any ideas?
Your code looks good, all you need to do is pass closures to the faultTolerant() method which call the methods you need:
class WidgetClient {
List<Widget> getAllWidgets() {
faultTolerant{_actuallyGetAllWidgets()}
}
void saveWidget(Widget w) {
faultTolerant{_actuallySaveWidget(w)}
}
void deleteWidget(Widget w) {
faultTolerant{_actaullyDeleteWidget(w)}
}
}
As your faultTolerant method takes a Closure as the final parameter, you can call it as I have shown in the code above, and this will pass the given closure (which simply calls your actually*Widget() methods) to the faultTolerantmethod.
I have a state machine that needs to call a different method on each object from a List of objects depending on the state I'm in. Basically I'm trying to refactor the code that has a loop in each case statement of my state machine so that it looks like the code below. However I cannot seem to figure out how to pass the relevant method to my refactored function (not to mention I then don't know how to call it on each item)
Any help would be appreciated.
Here's the example code:
public class MyOtherType
{
public bool Method1()
{ return false; }
public bool Method2()
{ return false; }
public bool Method3()
{ return false; }
public bool Method4()
{ return false; }
}
public class MyType
{
public enum MyState
{
DoSomething1,
DoSomething2,
DoSomething3,
DoSomething4
}
private MyState State = MyState.DoSomething1;
List<MyOtherType> MyListOfObjects = new List<MyOtherType>() { new MyOtherType(), new MyOtherType() };
private void StateMachine()
{
switch (State)
{
case MyState.DoSomething1:
//How do I pass this in? Do I need to set it up differnetly?
Process(() => MyOtherType.Method1());
break;
case MyState.DoSomething2:
Process(() => MyOtherType.Method2);
break;
case MyState.DoSomething3:
Process(() => MyOtherType.Method3);
break;
case MyState.DoSomething4:
Process(() => MyOtherType.Method4);
break;
}
}
private void Process(Func<bool> method)
{
foreach (MyOtherType item in MyListOfObjects)
{
//How do I call the method on each item?
if (item.method())
{
//Do something
}
}
}
}
I would suggest to get rid of such switch blocks and decouple each specific method from a state by introducing flexible map of strategy per state so it could be easily changed or even injected:
IDictionary<MyState, Func<bool>> strategyMap;
1) Fill it in
// if idea is to access methods without instance of MyOtherType -
// make all methods and class itself static so you can access it
// like MyOtherType.Method1
strategyMap = new Dictionary<MyState, Func<bool>>();
strategyMap.Add(MyState.DoSomething1, myOtherTypeInstance.Method1);
2) Call appropriate strategy depends on state instead of switch(State)
if (starategyMap.ContainsKey(State))
{
// pass in an associated strategy
Process(starategyMap[State]);
}
Feel free to ask in case of any questions
One possible solution is to make the methods static and take the class reference they shall operate on as a parameter:
public class MyOtherType
{
public static bool Method1(MyOtherType instance)
{
return instance == null;
}
}
I have the following scenario. The managed code will initialize lots of object of a class which is a wrapper around an unmanaged struct. There are two approaches that I can do for this. One is to have a managed class wrapper that just has a pointer to the unmanaged object. The other is to have a full fledged managed class and create the unmanaged object when required to call into unmanaged methods. I have provided both the methods below. I was told that if I use the approach 1(having a pointer to unmanged object), the GC will have lots of issue knowing about the unmanaged portion and it is better to do approach 2. Does someone tell me which is better or if there is some other approach that is even better. My concern with Approach 2 is that there are copying to and fro everytime a unmanaged method is called. I am not sure if the GC issue outweighs it.
EDIT- the first approach has a ref class and the second has a value class. The reason the second is value is so that it can be added to lists more efficiently
In unmanaged:
struct A_UNMANAGED
{
int a;
int b[20];
};
void GetData(A_UNMANAGED& a); // populates A
In managed (First Approach)
public ref class A_MANAGED
{
A_UNMANGED* ap;
public:
property System::UInt32 a
{
System::UInt32 get() { return ap->a; }
void set(System::UInt32 value) { ap->a = value; }
}
property array<System::UInt32>^ b
{
array<System::UInt32>^ get() { return ap->b; }
void set(array<System::UInt32>^ value) { b = value; } // assume this copy works
}
internal:
void GetData()
{
GetData(ap);
}
};
In managed (Second Approach) (EDIT: updated to ref. Assume all the garbage collection and pointer creation is written correctly)
public value class A_MANAGED
{
System::UInt32 a;
array<System::UInt32>^ b;
public:
property System::UInt32 a
{
System::UInt32 get() { return a; }
void set(System::UInt32 value) { a = value; }
}
property array<System::UInt32>^ b
{
array<System::UInt32>^ get() { return b; }
void set(array<System::UInt32>^ value) { b = value; }
}
internal:
void GetUnmanaged(A_UNMANAGED& obj1)
{
obj1.a = a;
pin_ptr<System::UInt32> bp = &b[0];
memcpy(obj1.b, bp, 20);
}
void GetData()
{
A_UNMANAGED obj2;
GetUnmanaged(obj2);
GetData(obj2);
// copy from obj2 to member variables
}
};
No, the 1st snippet it the canonical way. The garbage collector only moves the pointer, it doesn't move the pointed-to object. That one should have been allocated with malloc() or the new operator, it cannot be moved.
There are otherwise several serious problems in your code. You don't seem to allocate the memory for A_UNMANAGED unless GetData() takes its argument by reference. GetData() is never called. This must normally be a ref class (not ref value) so you can provide a destructor and a finalizer to release the memory. The b property setter will bomb your program with a StackOverflowException. Be sure to study the language before tackling this project.
Check this answer for sample code.
As Hans said, the first way is the usual approach (though personally, I think P/Invoke would be more succinct in this particular case...). However, your A_MANAGED::b implementation will not work, which would be obvious if one were to try simply compiling it. Try this instead:
public ref class A_MANAGED
{
A_UNMANAGED* ap;
public:
A_MANAGED() : ap(new A_UNMANAGED() ) { }
~A_MANAGED() { this->!A_MANAGED(); }
!A_MANAGED() { delete ap; ap = nullptr; }
property int a
{
int get() { return ap->a; }
void set(int value) { ap->a = value; }
}
property array<int>^ b
{
array<int>^ get()
{
using System::Runtime::InteropServices::Marshal;
array<int>^ arr = gcnew array<int>(20);
Marshal::Copy(System::IntPtr(ap->b), arr, 0, 20);
return arr;
}
void set(array<int>^ value)
{
using System::Runtime::InteropServices::Marshal;
Marshal::Copy(value, 0, System::IntPtr(ap->b), 20);
}
}
internal:
void GetData()
{
::GetData(*ap);
}
};
And then there's the usual caveat about returning arrays from properties: it's a bad idea. Unless you really want to maintain parity with the unmanaged class' public interface, b should really be a pair of set/get functions rather than a property.