I am using 2.2.4.400 of http://www.quartz-scheduler.net/. It is successfully working in other projects but not in this new one which is:
ASP.NET MVC 3, SQL Server back end
Based on ASP Boilerplate template (http://aspnetboilerplate.com/)
If I put a break point in the constructor for the class:
public class EmailQueueProcessJob : IJob
it is hit, however the execute never gets called. I have a break point placed at the top of:
public void Execute(IJobExecutionContext aContext)
{
}
Looking in the database I can see the jobs being created that they are supposedly "EXECUTING" but my Execute method is never called.
There is no code in the constructor, but clearly there must be an exception or something happening somewhere to prevent the execution. Any ideas on how I can track this down?
The solution ended up being to configure common logging and then have a look to see what is going wrong. The following will log to the trace window in VS. In my case there was an exception in one of the IJob constructor.
using colAlias = Common.Logging;
//Setup logging
colAlias.LogManager.Adapter = new colAlias.Simple.TraceLoggerFactoryAdapter { Level = colAlias.LogLevel.Info };
Related
I'm about to start using hangfire in C# in a asp.net mvc web application, and wonder how to create the right architecture.
As we are going to use HangFire, we are using it as a messagequeue, so we can process(store in the database) the user data directly and then for instance notify other systems and send email later in a separate process.
So our code now looks like this
function Xy(Client newClient)
{
_repository.save(newClient);
_crmConnector.notify(newClient);
mailer.Send(repository.GetMailInfo(), newClient)
}
And now we want to put the last two lines 'on the queue'
So following the example on the hangfire site we could do this
var client = new BackgroundJobClient();
client.Enqueue(() => _crmConnector.notify(newClient));
client.Enqueue(() => mailer.Send(repository.GetMailInfo(), newClient));
but I was wondering whether that is the right solution.
I once read about putting items on a queue and those were called 'commands', and they were classes especially created to wrap a task/command/thing-to-do and put it on a queue.
So for the notify the crm connector this would then be
client.Enqueue(() => new CrmNotifyCommand(newClient).Execute();
The CrmNotifyCommand would then receive the new client and have the knowledge to execute _crmConnector.notify(newClient).
In this case all items that are put on the queue (executed by HangFire) would be wrapped in a 'command'.
Such a command would then be a self containing class which knows how to execute a kind of business functionality. When the command itself uses more than 1 other class it could also be known as a facade I guess.
What do you think about such an architecture?
I once read about putting items on a queue and those were called
'commands', and they were classes especially created to wrap a
task/command/thing-to-do and put it on a queue.
Yes, your intuition is correct.
You should encapsulate all dependencies and explicit functionality in a separate class, and tell Hangfire to simply execute a single method (or command).
Here is my example, that I derived from Blake Connally's Hangfire demo.
namespace HangfireDemo.Core.Demo
{
public interface IDemoService
{
void RunDemoTask(PerformContext context);
}
public class DemoService : IDemoService
{
[DisplayName("Data Gathering Task Confluence Page")]
public void RunDemoTask(PerformContext context)
{
Console.WriteLine("This is a task that ran from the demo service.");
BackgroundJob.ContinueJobWith(context.BackgroundJob.Id, () => NextJob());
}
public void NextJob()
{
Console.WriteLine("This is my next task.");
}
}
}
And then separately, to schedule that command, you'd write something like the following:
BackgroundJob.Enqueue("demo-job", () => this._demoService.RunDemoTask(null));
If you need further clarification, I encourage you to watch Blake Connally's Hangfire demo.
I have an MVC Razor application that uses entity framework 6.0. However, if the DB is down or something, my code starts throwing exceptions at all kinds of random places like when I start evaluating my IEnumerable<T>s and IQueryable<T>s.
The model constructor is generated code that will be overwritten if I modify it which wouldn't help anyway because the constructor doesn't throw exceptions. Instead, the exceptions come in places like this
using (var dataContext = new ArchiveVMADDatabase.ArchiveDatabaseModel())
{
IQueryable<HDeploy> deploys = Helpers.GetProdDeploysFromArchive(dataContext);
var query = getBranchSelectListQuery(deploys);
listItems.AddRange(query);// EXCEPTION IF DB IS DOWN
}
Is there a good way for me to handle this in one place and avoid wrapping nearly 100% of my code in giant try catch blocks? I would really like to have it just return empty sets if it can't talk to the DB.
I'm not sure whether you are working with MVC or Web API, but in Web API one would use Exception Filters to centralize exception handling.
An exception filter is basically a derivative of the ExceptionFilterAttribute that can create a specific response depending on the caught exception:
public class NotImplExceptionFilterAttribute : ExceptionFilterAttribute
{
public override void OnException(HttpActionExecutedContext context)
{
if (context.Exception is NotImplementedException)
{
context.Response = new HttpResponseMessage(HttpStatusCode.NotImplemented);
}
}
}
You don't need to add try {} catch {} blocks anywhere -- Web API triggers the configured exception filters automatically as soon as an exception reaches the outer most layer of your system (i.e. the controller level).
You can activate an exception filter only for specific ApiControllers or globally for every controller.
I'm working on a project built on Asp.Net Boilerplate, and now I have to unit test the services using the real repositories with a real database connection (no mocking). I've been using the last post of BringerOd in https://gist.github.com/hikalkan/1e5d0f0142484da994e0 as a guide for setting up my UnitOfWorkScope instance. So, my code currently looks something like this:
IDisposableDependencyObjectWrapper<IUnitOfWork> _unitOfWork;
[TestInitialize]
public void SetUpService()
{
//initialize service
_unitOfWork = IocManager.Instance.ResolveAsDisposable<IUnitOfWork>();
UnitOfWorkScope.Current = _unitOfWork.Object;
UnitOfWorkScope.Current.Initialize(true);
UnitOfWorkScope.Current.Begin();
}
[TestCleanup]
public void CleanUpService()
{
UnitOfWorkScope.Current.Cancel();
_unitOfWork.Dispose();
UnitOfWorkScope.Current = null;
}
This works like a charm for the first unit test, but when I try to make a repository call in a second test, I get: "The operation cannot be completed because the DbContext has been disposed."
My guess is that when the TestInitialize method runs again, the unit of work scope is getting assigned with the same (disposed) DbContext, rather than a new one. I suppose, inside my actual test methods, I could set up my UnitOfWorkScope inside a using block with the IUnitOfWork. However, I really don't want to repeat that logic inside inside every single test. Does anyone know how to manually get the effect of a using block so that I get a brand new DbContext each time?
Check: http://aspnetboilerplate.com/Pages/Documents/Repositories
You must mark the calling method with [UnitOfWork] attribute.
The reason for this, as explained in the linked document is
When you call GetAll() out of a repository method, there must be an open database connection. This is because of deferred execution of IQueryable<T>. It does not perform database query unless you call ToList() method or use the IQueryable<T> in a foreach loop (or somehow access to queried items). So, when you call ToList() method, database connection must be alive. This can be achieved by marking caller method with the [UnitOfWork] attribute of ASP.NET Boilerplate. Note that Application Service methods are already using [UnitOfWork] as default, so, GetAll() will work without adding the [UnitOfWork] attribute for application service methods.
I've googled around the "Row Not Found or Changed" error for some time, and I'm just unable to see how the error is being caused in my application.
I have a facade class, called DataAccess, which wraps multiple repositories, and gets passed around my application. Every controller has a dependency upon DataAccess, so I've hooked it up to unity to pass out as required.
Data Access looks roughly like this, in truncated/abstracted form:
public class DataAccess : IDataAccess
{
private MyDataContext DataContext = new MyDataContext();
public Repository1 Repo1 = new Repository1();
public Repository2 Repo2 = new Repository2();
public DataAccess()
{
Repo1.DataContext = DataContext;
Repo2.DataContext = DataContext;
}
}
Then each controller has a dependency upon IDataAccess like so:
public class MyControllerBase
{
[Dependency]
IDataAccess DataAccess { get; set; }
}
Unity hands these out according to what appears to be normal configuration, registering types in Global.asax, hooking controllers up to a factory, resolving with unity. Furthermore, I've registered it with a PerThreadLifetimeManager(), which I am unsure whether is correct.
For the most part this works great - however the problem can be reproduced by:
Go to Edit action and post an edit (redirects to Index)
Go back into the Edit action and attempt to post another edit, OR, go into Delete action and attempt to post a Delete on the same item
This throws the "Row Not Found or Changed" error. Each action (Edit and Delete) calls SubmitChanges() on the DataContext. So I'm not quite sure what's going on here. If anyone has any ideas they would be extremely well received.
Cheers,
Tim.
I suspect the per-thread lifetime is not appropriate here - ASP.NET reuses threads across requests, and that would result in reusing your old contexts across multiple requests, possibly leaving them in odd states.
You have two choices:
If you only call container.resolve on the controller, then you could use the built-in PerResolveLifetimeManager instead. This would give you a single DataAccess object per controller resolve.
You could grab one of the many PerRequestLifetimeManager implementations and get a new DataAccess object per HttpRequest.
Either way will, I suspect, get you out of the issues you've got currently.
I'm using Visual Studio 2010 to write a simple C#/.NET GUI app, wherein I use a Logger class to write tracing/debugging info to a single file from within all of the various classes of the project. (See source code below.)
Each class's constructor writes an entry to the log when one of its object types is instantiated. One of those classes is a custom GUI controller component (class FileAttributesCtl), which is contained in a couple of the GUI forms used by the program.
The problem I'm having is that two logfiles are created, about 200 msec apart. The first logfile contains (only) a message that a FileAttributesCtl object has been constructed, and the second contains all of the other messages written to the (supposedly) shared logfile output stream. So every time I execute my project code, I get two logfiles.
Stranger still, every time I rebuild my project (F6), a logfile is created for the FileAttributesCtl object, indicating that an control object of this type is actually instantiated during the build process.
This apparently has something to do with threading. If the logfile is not named uniquely (i.e., if I do not append a unique date/time string to the filename), I get an exception, indicating that more than one process (which is actually the VS2010 process itself) is currently using the file.
So my question is: How do I get the singleton object to actually be a single object?
A secondary question is: Why is VS2010 acting this way?
//----------------------------------------
// Logger.cs
class Logger
{
// Singleton object
private static Logger s_logger =
new Logger("C:/Temp/foo.log");
public static Logger Log
{
get { return s_logger; }
}
private TextWriter m_out;
private Logger(string fname)
{
// Add a date/time suffix to the filename
fname = ...;
// Open/create the logging output file
m_out = new StreamWriter(
new FileStream(fname, FileMode.Create, FileAccess.Write,
FileShare.Read));
m_out.WriteLine(DateTime.Now.ToString(
"'$ 'yyyy-MM-dd' 'HH:mm:ss.fff"));
}
...
}
//----------------------------------------
// FileAttributesCtl.cs
public partial class FileAttributesCtl: UserControl
{
private Logger m_log = Logger.Log;
public FileAttributesCtl()
{
m_log.WriteLine("FileAttributesCtl()"); //Written to first logfile
InitializeComponent();
}
...
}
//----------------------------------------
// FileCopyForm.cs
public partial class FileCopyForm: Form
{
private Logger m_log = Logger.Log;
public FileCopyForm()
{
// Setup
m_log.WriteLine("FileCopyForm()"); //Written to second logfile
// Initialize the GUI form
m_log.WriteLine("FileCopyGui.InitializeComponent()");
InitializeComponent();
...
}
...
}
Note: This is very similar to a question from Dec 2009:
Access to singleton object from another thread
but it does not have the answers to my question.
Update
Further investigation shows that the VS2010 is indeed instantiating the custom component during the build, probably so that it can render it in the Designer window.
Also, there are indeed two separate threads calling the Logger constructor (each having a different ManagedThreadID).
Using a static class initializer to construct the singleton object does not work; I still get two logfiles.
Resolution
Upon closer examination, I notice that the custom control is getting instantiated twice, and this is being shown in both logfiles.
Therefore I think the problem is entirely due to the fact that VS instantiates the custom control object prior to executing the program that results in the first logfile being created. The second logfile is then created after the program starts normal execution.
Thus the first logfile is simply a side effect of the build process, and does not really have anything to do with multiple threads executing during normal program operation.
The obvious solution is to remove all logfile side-effect code from the component constructors. Or simply just ignore the first logfile altogether.
It could very well be that Visual Studio is building your UI component (to display in the designer) and in the process, your constructor is getting called which is why you're seeing that log file during the build process.
Static data + threads = trouble
You need to synchronize access to the singleton (and initialization of the singleton).
A static constructor may help
class Logger
{
private static Logger
static Logger()
{
s_logger = new Logger("C:/Temp/foo.log");
}
// ...
or better yet use a logging library (log4net) that handles all this stuff for you.
As for VS builds causing a log to be created, I'm not surprised. It is probably instantiating the forms to discover information about your forms via reflection.
update per comments
#LoadMaster "The static class initializer does not
work. I added more info to the logfile
output to include the current thread's
ManagedThreadID, and sure enough,
there are two different thread IDs
creating the two logfiles."
That's strange. Per MSDN
The static constructor for a class
executes at most once in a given
application domain. The execution of a
static constructor is triggered by the
first of the following events to occur
within an application domain:
An instance of the class is created.
Any of the static members of the class
are referenced.
Your thread must have moved AppDomains or there is some code missing from your snippets.