How to execute background task once?

Topics: Customizing Orchard, General
Aug 22, 2014 at 4:09 PM
I'm developing ContactForm module. When user submits form, custom module creates content item, and orchard workflow sends letters. Current code works slow, how to boost it up?
public ActionResult FormSubmit(FormSubmitViewModel model)
    if (!ModelState.IsValid || Request.Form.AllKeys.Any(x => x == "CheckField"))
        return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "Invalid model");
    var submission = _contentManager.Create("ContactSubmission", VersionOptions.Draft);
    var part = submission.Parts.FirstOrDefault(x => x.PartDefinition.Name == "ContactSubmission");
    if (part != null)
        foreach (var field in part.Fields)
            var value = Request.Form.Get(field.Name);
            if (value != null)
                SetFieldValue(field, value);
    return new EmptyResult();
I cannot use Task.Factory.StartNew for publish content item, because I'm getting exception:
Instances cannot be resolved and nested lifetimes cannot be created from this LifetimeScope as it has already been disposed.

Is there some pretty way to publish content item fast?
Aug 24, 2014 at 4:32 PM
I would first find out why this code is slow. You mention that you have a workflow sending letters. If that happens during content publication, then that might explain the poor performance (which would be in the workflow, not the above code). You can try this by disabling your workflow. If this is the case, then consider using the Jobs Queue to queue the sending of your letters. I think you could even take your form submission code and queue that. You would have to refactor it so that it is implemented as an IEventHandler I think. The invocation to that handler would be queued. Check out the Orchard.JobsQueue source code and its usage by Orchard.Email to see how this works. It's pretty awesome.
Aug 25, 2014 at 1:51 PM
Edited Aug 25, 2014 at 3:33 PM
Queued checkbox on email acitivty solve my problem.