I have the following code:
CreateMultiLayerWakeupSteps()
{
var wakeupStep = new AutodetectWakeupStep
{
//Creating the object...
}
//Later in the process I have this operation:
wakeupStep.SuccessNextStep = UserInputs(wakeupStep);
}
The UserInputs method implementation looks something like this:
private static AutodetectCommandStep UserInputs(AutodetectWakeupStep wakeupStep)
{
AutodetectCommandStep autodetectCommandStep
{
//Creating the object...
}
//Some more operations autodetectCommandStep here...
return autodetectCommandStep;
}
In the UserInputs method I would like to call the CreateMultiLayerWakeupStep method again in order to create a new step but the following exception is thrown: StackOverflowException.
Is there a solution to reuse the method while still running ? It is difficult to implement ? I am not familiar with threading asynchronization.
Best regards !
There is nothing about multithreading here. You are trying to make a recursion, but you don't specify when the recursion will end. Because of that you receive StackOverflowException.
So for example you should have a property in AutodetectCommandStep.ExecuteAgain
void CreateMultiLayerWakeupSteps()
{
var wakeupStep = new AutodetectWakeupStep
{
//Creating the object...
}
//Later in the process I have this operation:
wakeupStep.SuccessNextStep = UserInputs(wakeupStep);
if(wakeupStep.SuccessNextStep.ExecuteAgain)
CreateMultiLayerWakeupSteps();
}
You should decide when this ExecuteAgain will be false depending on your context so you will leave the method. If it is always true, it will throw same exception.
Also probably a good idea is to create the AutodetectWakeupStep object outside the CreateMultiLayerWakeupSteps(AutodetectWakeupStep wakeUpStep). And your code will look like this.
void CreateMultiLayerWakeupSteps(AutodetectWakeupStep wakeUpStep)
{
AutodetectWakeupStep step = UserInputs(wakeupStep);
if(step.ExecuteAgain)
CreateMultiLayerWakeupSteps(step);
}
Related
I am seeing some strange, buggy behavior in some .NET code, and I'm wondering if it has to do with how I've set things up.
I have a non-static class with a method. In this method, I create a new instance of a disposable class. I then use a static helper method to add something to that disposable instance.
Sometimes the code throws an exception at a certain point (by timing out). I don't know why, and this question isn't about why that happens. But what happens next is that if an exception was thrown, the next time the code runs, which supposedly would create a new instance of my main class, and a new instance of the disposable object within that new instance, then a different bit of code involving the disposable object also causes a timeout exception, much earlier in the process.
Here is a simplified example of what's happening:
public sealed class MyClass : OtherClass
{
protected override void MyMethod(ContextInfo context)
{
using (DisposableClass disposableInstance = new DisposableClass(context.URL))
{
Helper.ConditionallyAddThingy(disposableInstance, context.thingInfo, context.URL);
foreach(var foo in fooCollection)
{
// 1. initially I can make as many of these calls as I want,
// and they all finish successfully. if there were no
// timeout issues in section 2 below, the next time this
// runs, supposedly in a new instance of MyClass, and with
// a new instance of "disposableInstance", it again runs perfectly fine,
// no matter how many "foo"s there are.
// 2. see below
// 3. _if_ I had a timeout exception previously in section 2 below,
// the next time this runs, supposedly in a _new_ instance of MyClass,
// and with a _new_ instance of "disposableInstance",
// I get a timeout exception _here_ on the first "foo", and don't even get to section 2.
// make a call that does _not_ have to do with file streams
SomeResponse response = disposableInstance.AskForSomething(foo);
disposableInstance.ExecuteQuery();
}
foreach(var fileInfo in fileInfoCollection)
{
// 2. if there is only one file, the call succeeds, however
// if there is more than one file, the request for the
// second file casuses a System.Net.WebException: The operation has timed out
var fileUrl = fileInfo["URL"];
FileIshThing fileIsh = File.OpenBinaryDirect(disposableInstance, fileUrl);
disposableInstance.ExecuteQuery();
}
}
}
}
internal static class Helper
{
internal static void ConditionallyAddThingy(DisposableClass disposableInst, string thingInfo string contextUrl)
{
if (!string.IsNullOrWhiteSpace(thingInfo))
{
Thing thing = new Thing(thingInfo);
Uri uri = new Uri(contextUrl);
thing.Uri = uri;
ThingCollection collection = new ThingCollection();
collection.Add(thing);
disposabeInst.ExecuteWebRequestEventHandler += delegate (object sender, EventArgs eventArgs)
{
eventArgs.ThingCollection = collection;
}
}
}
}
Is there something about creating the Thing or ThingCollection, or adding the event receiver in the static method that makes those things static themselves, so that the next time through, I'm not really creating new ones but reusing the ones from the last time the method executed?
I don't understand how an error condition in a previous (and disposed of) instance of an object can affect a new instance of the object that may not necessarily meet the conditions for causing the error.
I ran into the "problem" that I'm quite often now reusing/copy'n'pasting code that checks if a nHibernate ISession is currently in a transaction and if not starts one.
Now I thought it would be nice if I just made a static method in a utility class that I can provide with an ISession object and a delegate that contains the actual database code and then use just that method to encapsulate that stuff in a transaction if there wasn't one ongoing just yet.
So here's what I came up with.
public static class TransactionUtils
{
public static void EncloseInTransaction(ISession session, Action<ISession> codeToEnclose)
{
if (session == null)
throw new ArgumentNullException("session");
var isInTrans = session.Transaction != null && session.Transaction.IsActive;
var tx = isInTrans ? session.Transaction : session.BeginTransaction();
try
{
codeToEnclose(session);
if (!isInTrans)
tx.Commit();
}
catch (Exception e)
{
tx.Rollback();
throw;
}
finally
{
if (!isInTrans)
tx.Dispose();
}
}
}
So this is all nice and well I guess. But using that code looks something like this.
TransactionUtils.EncloseInTransaction(session, session1 =>
{
session1.Query<Blahblah>().Where(x.Blub == "meh").ToList();
session1.CreateQuery("update Foo set Urgs=:Moo where Id=:Id")
.SetParameter("moo", "baaahh")
.SetParameter("Id", 12305)
.ExecuteUpdate();
} );
I don't really like the (session, session1 =>...) part here. Looks confusing as hell and someone could just use session instead of session1 inside the code passed to the delegate.
So basically my question is. Would it actually be a problem if I ditched the Action<ISession> and replaced it with only Action and then just used session inside the code? I know there's much magic happening there but as i understand it if i reference session inside the delegates code the compiler provides a pointer to the session object inside there. Or something or other. And i could basically just use that.
You can make that method an extension method, that should make the code look much nicer.
public static void EncloseInTransaction(this ISession session, Action<ISession> codeToEnclose)
And calling the method:
session.EncloseInTransaction(s =>
{
s.Query<Blahblah>().Where(x.Blub == "meh").ToList();
s.CreateQuery("update Foo set Urgs=:Moo where Id=:Id")
.SetParameter("moo", "baaahh")
.SetParameter("Id", 12305)
.ExecuteUpdate();
});
You can also use Action like you said (which is ok) and it would look like this:
public static void EncloseInTransaction(this ISession session, Action codeToEnclose)
Calling the method:
session.EncloseInTransaction(() =>
{
session.Query<Blahblah>().Where(x.Blub == "meh").ToList();
session.CreateQuery("update Foo set Urgs=:Moo where Id=:Id")
.SetParameter("moo", "baaahh")
.SetParameter("Id", 12305)
.ExecuteUpdate();
});
I have a class in my program of which I want only one copy. I don't want to use the Singleton pattern though for a couple of reasons (* see below). I know that I'll only have one copy of the class because I'll be the only one calling its constructor.
In my class's constructor, I want to check that only one copy of the class will exist and throw an exception if more than one exists. Is the code below a good pattern to use for this case?
public class MySingletonAlternative : IDisposable
{
private static int _count = 0;
public MySingletonAlternative()
{
int newValue = System.Threading.Interlocked.Increment(ref _count);
if (newValue > 1)
{
throw new NotImplementedException();
}
}
public void Dispose()
{
int newValue = System.Threading.Interlocked.Decrement(ref _count);
if (newValue < 0)
{
throw new ObjectDisposedException("MySingletonAlternative");
}
}
}
* Why I don't want to use a Singleton:
I want to be able to control when the class is created. In the traditional C# Singleton pattern, construction happens non-deterministically.
I want to avoid global variables.
When I'm debugging my code and an exception is raised in the Singleton's private constructor, Visual Studio highlights the exception, but it highlights the wrong line of code, usually in a different file.
I don't want to create this object lazily (using Lazy<T>). One instance of this class will exist for the life of my application. I gain nothing by constructing it lazily.
Use a IoC Container like an UnityContainer. It will erase all of your points you've mentioned why you don't want to use a Singleton (in the means of global variables or static). You will be able to fully controll the creation of your lifetime-instance and inject it into all classes that will need to use this.
Can you use dependency injection and then have the di container manage the lifetime of the class you want to create? an example is with Unity and the ContainerControlledLifetimeManager
http://msdn.microsoft.com/en-us/library/dn178463(v=pandp.30).aspx#sec34
DON'T USE THIS CODE BELOW IN REAL APPLICATIONS! It's just for demo purposes.
I guess it's not a good way, but it looks like that your approach will work just fine. I am not aware of edge cases though.
Just created a little test app to create 1 million instances in a for loop and count
the exceptions it raises.
In this case it should be: 1 instance successfully created and 999.000 exceptions raised.
I ran the test app a couple of times and it always returned 999.000.
Depending on your machine this code could take some time to finish,
cause it throws 999.000 exceptions.
public static volatile int _global_Exception_count = 0;
static async Task Main(string[] args)
{
_global_Exception_count = 0;
var list = Enumerable.Range(1, 1000000).ToList();
var tlist = list.Select(async item =>
{
MySingletonAlternative current = null;
try
{
current = new MySingletonAlternative();
}
catch (Exception ex) { System.Threading.Interlocked.Increment(ref _global_Exception_count); }
return await Task.FromResult(0);
});
await Task.WhenAll(tlist);
Console.WriteLine(_global_Exception_count);
}// end main
The most confusing error I have ever seen in ASP. I have done method calls like this before, and have no issue in other spots of my code.
First of all the class:
namespace LocApp.Helpers.Classes.LocationHelper
{
public class QueryHelper
{
private LocAppContext db = new LocAppContext();
public static IEnumerable<Service> getAllService()
{
using (var db = new LocAppContext())
{
var service = db.Locations.Include(s => s.LocationAssignment);
var serv = (from s in db.Services
where s.active == true
select s).ToList();
return serv;
}
}
}
}
Pretty easy to understand whats going on. So lets call the method:
IEnumerable<LocApp.Models.Service> Service = new LocApp.Helpers.Classes.LocationHelper.QueryHelper.getAllService(Model.id);
getAllServices(Model.id) is throwing the error "is a method but treated like a type" , um no its not be treated like a type....
whats going on?
Well it's exactly as the error message says. getAllService() is a method:
public static IEnumerable<Service> getAllService()
But you're trying to use it as if it were a type with a constructor:
Service = new LocApp.Helpers.Classes.LocationHelper.QueryHelper.getAllService(...)
The new part is the mistake here. You don't want to call a constructor, you just want to call a method. It's a static method, so you don't need an instance - you can just use:
Service = LocApp.Helpers.Classes.LocationHelper.QueryHelper.getAllService(...)
Note that if you have appropriate using directives, follow .NET naming conventions and take care about singular/plural names, your code will be easier to follow:
var services = QueryHelper.GetAllServices(...);
Do you not simply mean:
IEnumerable<LocApp.Models.Service> Service = LocApp.Helpers.Classes.LocationHelper.QueryHelper.getAllService();
Get rid of the new bit, essentially, and that method doesn't take any parameters either - I'd assume you'd run into that problem after you removed the new bit.
Your getAllService method doesn't take any arguments, so you should call it without. Also it is a static method so don't use the new keyword:
IEnumerable<LocApp.Models.Service> Service = LocApp.Helpers.Classes.LocationHelper.QueryHelper.getAllService();
This is the point, I have a WCF service, it is working now. So I begin to work on the client side. And when the application was running, then an exception showed up: timeout. So I began to read, there are many examples about how to keep the connection alive, but, also I found that the best way, is create channel, use it, and dispose it. And honestly, I liked that. So, now reading about the best way to close the channel, there are two links that could be useful to anybody who needs them:
1. Clean up clients, the right way
2. Using Func
In the first link, this is the example:
IIdentityService _identitySvc;
...
if (_identitySvc != null)
{
((IClientChannel)_identitySvc).Close();
((IDisposable)_identitySvc).Dispose();
_identitySvc = null;
}
So, if the channel is not null, then is closed, disposed, and assign null. But I have a little question. In this example the channel has a .Close() method, but, in my case, intellisense is not showing a Close() method. It only exists in the factory object. So I believe I have to write it. But, in the interface that has the contracts or the class that implemets it??. And, what should be doing this method??.
Now, the next link, this has something I haven't try before. Func<T>. And after reading the goal, it's quite interesting. It creates a funcion that with lambdas creates the channel, uses it, closes it, and dipose it. This example implements that function like a Using() statement. It's really good, and a excellent improvement. But, I need a little help, to be honest, I can't understand the function, so, a little explanatino from an expert will be very useful. This is the function:
TReturn UseService<TChannel, TReturn>(Func<TChannel, TReturn> code)
{
var chanFactory = GetCachedFactory<TChannel>();
TChannel channel = chanFactory.CreateChannel();
bool error = true;
try {
TReturn result = code(channel);
((IClientChannel)channel).Close();
error = false;
return result;
}
finally {
if (error) {
((IClientChannel)channel).Abort();
}
}
}
And this is how is being used:
int a = 1;
int b = 2;
int sum = UseService((ICalculator calc) => calc.Add(a, b));
Console.WriteLine(sum);
Yep, I think is really, really good, I'd like to understand it to use it in the project I have.
And, like always, I hope this could be helpful to a lot of people.
the UseService method accepts a delegate, which uses the channel to send request. The delegate has a parameter and a return value. You can put the call to WCF service in the delegate.
And in the UseService, it creates the channel and pass the channel to the delegate, which should be provided by you. After finishing the call, it closes the channel.
The proxy object implements more than just your contract - it also implements IClientChannel which allows control of the proxy lifetime
The code in the first example is not reliable - it will leak if the channel is already busted (e.g. the service has gone down in a session based interaction). As you can see in the second version, in the case of an error it calls Abort on the proxy which still cleans up the client side
You can also do this with an extension method as follows:
enum OnError
{
Throw,
DontThrow
}
static class ProxyExtensions
{
public static void CleanUp(this IClientChannel proxy, OnError errorBehavior)
{
try
{
proxy.Close();
}
catch
{
proxy.Abort();
if (errorBehavior == OnError.Throw)
{
throw;
}
}
}
}
However, the usage of this is a little cumbersome
((IClientChannel)proxy).CleanUp(OnError.DontThrow);
But you can make this more elegant if you make your own proxy interface that extends both your contract and IClientChannel
interface IPingProxy : IPing, IClientChannel
{
}
To answer the question left in the comment in Jason's answer, a simple example of GetCachedFactory may look like the below. The example looks up the endpoint to create by finding the endpoint in the config file with the "Contract" attribute equal to the ConfigurationName of the service the factory is to create.
ChannelFactory<T> GetCachedFactory<T>()
{
var endPointName = EndPointNameLookUp<T>();
return new ChannelFactory<T>(endPointName);
}
// Determines the name of the endpoint the factory will create by finding the endpoint in the config file which is the same as the type of the service the factory is to create
string EndPointNameLookUp<T>()
{
var contractName = LookUpContractName<T>();
foreach (ChannelEndpointElement serviceElement in ConfigFileEndPoints)
{
if (serviceElement.Contract == contractName) return serviceElement.Name;
}
return string.Empty;
}
// Retrieves the list of endpoints in the config file
ChannelEndpointElementCollection ConfigFileEndPoints
{
get
{
return ServiceModelSectionGroup.GetSectionGroup(
ConfigurationManager.OpenExeConfiguration(
ConfigurationUserLevel.None)).Client.Endpoints;
}
}
// Retrieves the ConfigurationName of the service being created by the factory
string LookUpContractName<T>()
{
var attributeNamedArguments = typeof (T).GetCustomAttributesData()
.Select(x => x.NamedArguments.SingleOrDefault(ConfigurationNameQuery));
var contractName = attributeNamedArguments.Single(ConfigurationNameQuery).TypedValue.Value.ToString();
return contractName;
}
Func<CustomAttributeNamedArgument, bool> ConfigurationNameQuery
{
get { return x => x.MemberInfo != null && x.MemberInfo.Name == "ConfigurationName"; }
}
A better solution though is to let an IoC container manage the creation of the client for you. For example, using autofac it would like the following. First you need to register the service like so:
var builder = new ContainerBuilder();
builder.Register(c => new ChannelFactory<ICalculator>("WSHttpBinding_ICalculator"))
.SingleInstance();
builder.Register(c => c.Resolve<ChannelFactory<ICalculator>>().CreateChannel())
.UseWcfSafeRelease();
container = builder.Build();
Where "WSHttpBinding_ICalculator" is the name of the endpoint in the config file. Then later you can use the service like so:
using (var lifetime = container.BeginLifetimeScope())
{
var calc = lifetime.Resolve<IContentService>();
var sum = calc.Add(a, b);
Console.WriteLine(sum);
}