I have a function that executes some SQL commands, and I've created a logger that I write in the file the command that was executed and the number of rows that were affected, but I also need to write down the command that may have raised an OracleException, so I've done this piece of code:
public string ExecuteCommand(List<string> comandos)
{
var excepção = string.Empty;
var executar = new OracleCommand
{
Connection = Updater.OraConnection,
CommandType = CommandType.Text
};
try
{
Logg("Inicio da execução de comandos");
foreach (var variable in comandos)
{
excepção = variable;
executar.CommandText = variable;
throw new OracleException(0, "comando", "stuff", "adasds");
var Afectados = executar.ExecuteNonQuery();
Logg(variable);
Logg("Linhas afectadas: " + Afectados);
}
}
catch (OracleException)
{
Logg("Erros:");
Logg(excepção);
return excepção;
}
return excepção;
}
I've tried to search everywhere but I cant fint any suitable or even focused answers, so Im kinda lost for why cant I raise an oracleException as I did like this: throw new OracleException(0, "comando", "stuff", "adasds");
It just says that Cannot access constructor here due to its protection level.
Any help would be aprecciated
If you just want to simulate the exception being thrown and do not care about interrogating the object then.
private OracleResilienceManager CreateSut()
{
return new OracleResilienceManager(_resilienceSettings);
}
throw System.Runtime.Serialization.CreateSafeUninitializedProtectedType<OracleException>();
In my case I was testing a retry policy and wanted to test the retry logic when this exception is thrown. Had no need to access the object itself.
public class OracleException : Exception
{
}
The class needs to have its scope set to public or internal. The constructor cannot be accessed as its a private class.
Related
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);
}
Note: I've went through millions of questions when the issue is not disposing the reader/connection properly, or when the error is because of badly handled lazy loading. I believe that this issue is a different one, and probably related to MySQL's .NET connector.
I'm using MySQL server (5.6) database extensively through its .NET connector (6.8.3). All tables are created with MyISAM engine for performance reasons. I have only one process with one thread (update: in fact, it's not true, see below) accessing the DB sequentially, so there is no need for transactions and concurrency.
Today, after many hours of processing the following piece of code:
public IEnumerable<VectorTransition> FindWithSourceVector(double[] sourceVector)
{
var sqlConnection = this.connectionPool.Take();
this.selectWithSourceVectorCommand.Connection = sqlConnection;
this.selectWithSourceVectorCommand.Parameters["#epsilon"].Value
= this.epsilonEstimator.Epsilon.Min() / 10;
for (int d = 0; d < this.dimensionality; ++d)
{
this.selectWithSourceVectorCommand.Parameters["#source_" + d.ToString()]
.Value = sourceVector[d];
}
// *** the following line (201) throws the exception presented below
using (var reader = this.selectWithSourceVectorCommand.ExecuteReader())
{
while (reader.Read())
{
yield return ReaderToVectorTransition(reader);
}
}
this.connectionPool.Putback(sqlConnection);
}
threw the following exception:
MySqlException: There is already an open DataReader associated with this Connection which must be closed first.
Here is the relevant part of the stack trace:
at MySql.Data.MySqlClient.ExceptionInterceptor.Throw(Exception exception)
at MySql.Data.MySqlClient.MySqlConnection.Throw(Exception ex)
at MySql.Data.MySqlClient.MySqlCommand.CheckState()
at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader(CommandBehavior behavior)
at MySql.Data.MySqlClient.MySqlCommand.ExecuteReader()
at implementation.VectorTransitionsMySqlTable.d__27.MoveNext() in C:\Users\bartoszp...\implementation\VectorTransitionsMySqlTable.cs:line 201
at System.Linq.Enumerable.d__3a1.MoveNext()
at System.Linq.Buffer1..ctor(IEnumerable1 source)
at System.Linq.Enumerable.ToArray[TSource](IEnumerable1 source)
at implementation.VectorTransitionService.Add(VectorTransition vectorTransition) in C:\Users\bartoszp...\implementation\VectorTransitionService.cs:line 38
at Program.Go[T](Environment`2 p, Space parentSpace, EpsilonEstimator epsilonEstimator, ThresholdEstimator thresholdEstimator, TransitionTransformer transitionTransformer, AmbiguityCalculator ac, VectorTransitionsTableFactory vttf, AxesTableFactory atf, NeighbourhoodsTableFactory ntf, AmbiguitySamplesTableFactory astf, AmbiguitySampleMatchesTableFactory asmtf, MySqlConnectionPool connectionPool, Boolean rejectDuplicates, Boolean addNew) in C:\Users\bartoszp...\Program.cs:line 323
The connectionPool.Take returns the first connection that satisfies the following predicate:
private bool IsAvailable(MySqlConnection connection)
{
var result = false;
try
{
if (connection != null
&& connection.State == System.Data.ConnectionState.Open)
{
result = connection.Ping();
}
}
catch (Exception e)
{
Console.WriteLine("Ping exception: " + e.Message);
}
return result && connection.State == System.Data.ConnectionState.Open;
}
(This is related to my previous question, when I resolved a different, but similar issue: MySQL fatal error during information_schema query (software caused connection abort))
The FindWithSourceVector method is called by the following piece of code:
var existing
= this.vectorTransitionsTable
.FindWithSourceVector(vectorTransition.SourceVector)
.Take(2)
.ToArray();
(I need to find at most two duplicate vectors) - this is the VectorTransitionService.cs:line 38 part of the stack trace.
Now the most interesting part: when the debugger stopped execution after the exception occured, I've investigated the sqlConnection object to find, that it doesn't have a reader associated with it (picture below)!
Why is this happening (apparently at "random" - this method was being called almost every minute for the last ~20h)? Can I avoid that (in ways other then guess-adding some sleeps when Ping throws an exception and praying it'll help)?
Additional information regarding the implementation of the connection pool:
Get is intended for methods that call only simple queries and are not using readers, so the returned connection can be used in a re-entrant way. It is not used directly in this example (because of the reader involved):
public MySqlConnection Get()
{
var result = this.connections.FirstOrDefault(IsAvailable);
if (result == null)
{
Reconnect();
result = this.connections.FirstOrDefault(IsAvailable);
}
return result;
}
The Reconnect method just iterates though the whole array and recreates and opens the connections.
Take uses Get but also removes the returned connection from the list of available connections so in case of some methods that during their usage of a reader call other methods that also need a connection, it will not be shared. This is also not the case here, as the FindSourceVector method is simple (doesn't call other methods that use the DB). However, the Take is used for the sake of convention - if there is a reader, use Take:
public MySqlConnection Take()
{
var result = this.Get();
var index = Array.IndexOf(this.connections, result);
this.connections[index] = null;
return result;
}
Putback just puts a connection to the first empty spot, or just forgets about it if the connection pool is full:
public void Putback(MySqlConnection mySqlConnection)
{
int index = Array.IndexOf(this.connections, null);
if (index >= 0)
{
this.connections[index] = mySqlConnection;
}
else if (mySqlConnection != null)
{
mySqlConnection.Close();
mySqlConnection.Dispose();
}
}
I suspect this is the problem, at the end of the method:
this.connectionPool.Putback(sqlConnection);
You're only taking two elements from the iterator - so you never complete the while loop unless there's actually only one value returned from the reader. Now you're using LINQ, which will automatically be calling Dispose() on the iterator, so your using statement will still be disposing of the reader - but you're not putting the connection back in the pool. If you do that in a finally block, I think you'll be okay:
var sqlConnection = this.connectionPool.Take();
try
{
// Other stuff here...
using (var reader = this.selectWithSourceVectorCommand.ExecuteReader())
{
while (reader.Read())
{
yield return ReaderToVectorTransition(reader);
}
}
}
finally
{
this.connectionPool.Putback(sqlConnection);
}
Or ideally, if your connection pool is your own implementation, make Take return something which implements IDisposable and returns the connection back to the pool when it's done.
Here's a short but complete program to demonstrate what's going on, without any actual databases involved:
using System;
using System.Collections.Generic;
using System.Linq;
class DummyReader : IDisposable
{
private readonly int limit;
private int count = -1;
public int Count { get { return count; } }
public DummyReader(int limit)
{
this.limit = limit;
}
public bool Read()
{
count++;
return count < limit;
}
public void Dispose()
{
Console.WriteLine("DummyReader.Dispose()");
}
}
class Test
{
static IEnumerable<int> FindValues(int valuesInReader)
{
Console.WriteLine("Take from the pool");
using (var reader = new DummyReader(valuesInReader))
{
while (reader.Read())
{
yield return reader.Count;
}
}
Console.WriteLine("Put back in the pool");
}
static void Main()
{
var data = FindValues(2).Take(2).ToArray();
Console.WriteLine(string.Join(",", data));
}
}
As written - modelling the situation with the reader only finding two values - the output is:
Take from the pool
DummyReader.Dispose()
0,1
Note that the reader is disposed, but we never get as far as returning anything from the pool. If you change Main to model the situation where the reader only has one value, like this:
var data = FindValues(1).Take(2).ToArray();
Then we get all the way through the while loop, so the output changes:
Take from the pool
DummyReader.Dispose()
Put back in the pool
0
I suggest you copy my program and experiment with it. Make sure you understand everything about what's going on... then you can apply it to your own code. You might want to read my article on iterator block implementation details too.
TyCobb and Jon Skeet have correctly guessed, that the problem was the pool implementation and multi-threading. I forgot that actually I did start some tiny Tasks in the Reconnect method. The first connection was created and opened synchronously but all other where opened asynchronously.
The idea was that because I only need one connection at time, there others can reconnect in different threads. However, because I didn't always put the connection back (as explained in Jon's answer) reconnecting was happening quite frequently, and because the system was quite loaded these reconnection threads weren't fast enough, which eventually led to race conditions. The fix is to reconnect in a more simple and straightforward manner:
private void Reconnect()
{
for (int i = 0; i < connections.Length; ++i)
{
if (!IsAvailable(this.connections[i]))
{
this.ReconnectAt(i);
}
}
}
private void ReconnectAt(int index)
{
try
{
this.connections[index] = new MySqlConnection(this.connectionString);
this.connections[index].Open();
}
catch (MySqlException mse)
{
Console.WriteLine("Reconnect error: " + mse.Message);
this.connections[index] = null;
}
}
I am new at Entity Framework Code first and I am building a small app to get used to it.When the site runs for the first time I access existing catalog values inside the database and display this in a drop down using razor.
public void GetCats()
{
using (context = new RecipeContext())
{
try
{
var query = (from r in context.Catalogues
select r).Distinct().ToList();
catalogues = query.Select(t => t.CatalogueName.ToString()).ToList();
catalogues.Sort();
}
catch (Exception exe)
{
labMessage = exe.Message;
}
}
}
Now when I try to add Catalogue values to the context I get the above error.
public void AddCatalogue(string catalogueName)
{
using(context = new RecipeContext())
{
try
{
catalogueName = catalogueName.ToLower();
var catalogue = new RecipeCatalogue { CatalogueName = catalogueName };
if (context.Catalogues.Where(t => t.CatalogueName == catalogueName).Count() > 0)
{
labMessage = "The value already exists";
CatalogueNameAdded = false;
return;
}
context.Catalogues.Add(catalogue);
context.SaveChanges();
catalogueNameAdded = true;
labMessage = "a new catalogue record was added";
}
catch (Exception exe)
{
catalogueNameAdded = false;
labMessage = exe.Message;
}
}
}
The values are being added to the database however but still get the above exception.
Advice perhaps as to why I get this error. This is my Controller method which calls the above method.
[HttpPost]
public JsonResult AddNewCatalogue(string catalogueName)
{
ViewModel model = new ViewModel();
model.AddCatalogue(catalogueName);
return Json(new { ViewModel = model });
}
Is context a field in your model?
I think you shouldn't assign to a field in a using statement. At the closing brace of the using context will be disposed. If you access that field in another place (without re-assigning) you are accessing a disposed object that might raise the exception you are getting.
Try changing your using statetments like this using (var context = new RecipeContext()).
(note var before context) and drop the field.
Your context is being disposed when the using block where you're performing your query is exited. That's the whole point of the using statement:
using(context = new RecipeContext()) {
// ...
}
// context has been disposed at this point
Instead of a using statement, give your class a field to hold a reference to it.
private RecipeContext _context;
public void GetCats() {
_context = new RecipeContext();
// ...
}
public void AddCatalogue(string catalogueName) {
// Use _context here
}
Just make sure that at some point, you call _context.Dispose(). Also, it's probably better to create the context in the constructor or someplace else that's only called once, prior to performing any operations with it.
Just my 2 cents:
The above answers are correct! If you're using some pattern like a repository, I sugest to implement it as a singleton! This way your objects will not be detached, and you're context will not be disposed!
Can anyone help with the following code?
I'm trying to pass value from server to client via RIA Silverlight, but keep getting NullReferenceException.
I have removed all other attempts that I have tried and have just posted last attempt.
Server-side Code
namespace Web.UI.SilverlightDomainServices
{
// Implements application logic using the SilverlightDBEntities context.
// TODO: Add your application logic to these methods or in additional methods.
// TODO: Wire up authentication (Windows/ASP.NET Forms) and uncomment the following to disable anonymous access
// Also consider adding roles to restrict access as appropriate.
// [RequiresAuthentication]
[EnableClientAccess()]
public class VideoAdvertDomainService : LinqToEntitiesDomainService<SilverlightDBEntities>
{
// TODO:
// Consider constraining the results of your query method. If you need additional input you can
// add parameters to this method or create additional query methods with different names.
// To support paging you will need to add ordering to the 'at_AdvertVideoAdvertisement' query.
string strMonthYear = DateTime.Now.ToString("MMMM-yyyy");
[Invoke]
public List<string> GetMediaURLBasedOnMonthYear(string strMonthYear)
{
return (from p in this.ObjectContext.at_AdvertVideoAdvertisement
where p.AdvertMediaMonthYear == strMonthYear
select p.AdvertMediaURL).ToList();
}
public IQueryable<at_AdvertVideoAdvertisement> GetAt_AdvertVideoAdvertisement()
{
return this.ObjectContext.at_AdvertVideoAdvertisement;
}
}
}
Client-side Code
namespace Web.Silverlight
{
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
Loaded += new RoutedEventHandler(MainPage_Loaded);
}
private VideoAdvertDomainContext ctx = new VideoAdvertDomainContext();
private void MainPage_Loaded(object sender, RoutedEventArgs e)
{
string strMonthYear = DateTime.Now.ToString("MMMM-yyyy");
VideoAdvertDomainContext DomainContext = new VideoAdvertDomainContext();
InvokeOperation iv = DomainContext.GetMediaURLBasedOnMonthYear("September-2012");
iv.Value.ToString();
PlaylistItem item = new PlaylistItem();
item.MediaSource = new Uri(iv.Value.ToString());
item.DeliveryMethod = Microsoft.SilverlightMediaFramework.Plugins.Primitives.DeliveryMethods.AdaptiveStreaming;
MP.Playlist.Add(item);
}
}
}
Without seeing the stack trace from the exception, I have to guess.
Possibility 1
It could be that ObjectContext is null and therefore, this line will throw the exception you are getting.
return (from p in this.ObjectContext.at_AdvertVideoAdvertisement
where p.AdvertMediaMonthYear == strMonthYear
select p.AdvertMediaURL).ToList();
Possibility 2
Is there a chance that the contents of this.ObjectContext.at_AdvertVideoAdvertisement are null?
If so, p could be null, which would cause the query to throw the exception.
Possibility 3
I suspect the offending line is:
iv.Value.ToString();
This line does nothing, but you also repeat this a couple of lines later in a useful context, so perhaps the first declaration is a mistake. However, this assumes that the InvokeOperation value returned by VideoAdvertDomainContext.GetMediaURLBasedOnMonthYear is not null and that its Value property is not null. This may not be the case.
Recommendation
I recommend placing a breakpoint on those lines and seeing what the variables look like in the debugger to track down the null reference. From there, you can start to work out why it is null and either make it so that it isn't, or fix your code so that it copes appropriately with null references.
If you call a constructor from a within a using statement the object is automatically disposed is wrapped it with a try/catch block. That is an object initializer block in the constructor.
But what becomes with member types that are initialized in the same statement? e.g:
class TypeThatThrowsAnException
{
public TypeThatThrowsAnException()
{
throw new Exception();
}
}
using (SomeDisposable ds = new SomeDisposable() {
MemberThatThrowsAnException m = new TypeThatThrowsAnException()
})
{
// inside using statement
ds.doSomething();
}
What happens with MemberThatThrowsAnException when it throws an exception when SomeDisposable is initialized, i.e., the code block is executed?
And does it make any difference if we call those members constructors outside the scope of the using block?
class TypeThatThrowsAnException
{
public TypeThatThrowsAnException()
{
throw new Exception();
}
}
class SomeClass
{
public static TypeThatThrowsAnException StaticMember
{
get
{
return new TypeThatThrowsAnException();
}
}
}
using (SomeDisposable ds = new SomeDisposable() {
MemberThatThrowsAnException = SomeClass.StaticMember
})
{
// inside using statement
ds.doSomething();
}
In some scenarios this can be pretty nice and readable, but I would like to know if thare are any caveats or pitfalls in this way. Or that it is a no-go all the way. Besides that you need to keep the readability in mind.
Object initializers are in some sense a red herring here... but they're one example of where a problem is avoidable.
The object isn't "guarded" by the using statement until the resource acquisition expression has completed normally. In other words, your code is like this:
SomeDisposable tmp = new SomeDisposable();
tmp.MemberThatThrowsAnException = new TypeThatThrowsAnException();
using (SomeDisposable ds = tmp)
{
// Stuff
}
That's more obviously problematic :)
Of course the solution is to assign the property inside the using statement:
using (SomeDisposable ds = new SomeDisposable())
{
MemberThatThrowsAnException = new TypeThatThrowsAnException();
// Stuff
}
Now we're only relying on the constructor of SomeDisposable to clean up after itself if it ends up throwing an exception - and that's a more reasonable requirement.
Find this post on Ayende's blog on the subject. It's about object initializers in using statements but it seems somehow related to your question.
From what I can see, your SomeDisposable class has a property of type TypeThatThrowsAnException, that you're initializing as you instantiate the SomeDisposable - yes ?
using () i.e. the Dispose pattern is a short-hand that actually emits this: -
SomeDisposable ds = null;
try
{
ds = new SomeDisposable();
}
finally
{
if (ds != null)
ds.Dispose();
}
So if the constructor for your type throws an exception, control will immediately pass to the finally block.