Code Optimization

Interesting things about software development and code optimization

Top 1 Anti-Spam Contact Form

The Best Anti-Spam Contact Form for Your Website 


Hello friends,

today I'm going to share my experience with implementing the best, in my opinion, anti-spam mechanism for web contact form.

There is well known problem - when you have a contact form on your website then you will get a lot of spam submitted via the form action url on your website and this is very annoying as for me. So I started thinking on how to do it in a way so I would get no spam at all or as less as possible at least.

First thing that came in my mind was that we would need a dynamic and random form action url for the form submission that will return HTTP 404 not found in case user would not pass human-like verification with a captcha or would try to guess the url.

As I work with C#.NET + MVC I started creating such solution with ASP.NET MVC and actually here is what I came up to.

First thing we need is to register our website for google reCAPTCHA v2, get public and secret keys and add reCAPTCHA to an our contact form. Note that in our case we need to render reCAPTCHA by hand and here is the Contact View html:


@section head
{
    <script src="https://www.google.com/recaptcha/api.js?onload=renderRecaptcha&render=explicit" async defer></script>
}

...

    @using (Html.BeginForm("", "", FormMethod.Post, new { id="contactForm" }))
    {
        @Html.AntiForgeryToken()

        ...

        <div id="ReCaptchContainer"></div>

        ...
        
        <input type="submit" value="Send" />
    }

...

@section scripts
{
    <script>
        var your_site_key = '.....-....';
        var canProceed = false;

        var reCaptchaCallback = function (response) {
            //lets go to server, validate a token and return a random url if succeed
            $.ajax({
                method: "POST",
                url: "/Contact/IsReCaptchValid",
                cache: false,
                data: {
                    gRecaptchaResponse: response
                }
            }).done(function (html) {
                if (html != "none") {
                    $("#contactForm").attr("action", html);
                    canProceed = true;
                    $("#submit").removeClass("disabled");
                    $("#submit").addClass("btn-success");
                }
            });
        };

        var renderRecaptcha = function () {
            //lets render our captcha
            grecaptcha.render('ReCaptchContainer', {
                'sitekey': your_site_key,
                'callback': reCaptchaCallback
            });
        };

        $(document).ready(function () {
            $("input[type='submit']").on("click", function (e) {

                ...

                if (canProceed != true) {
                    //CAPTCHA has not been validated yet
                    e.stopPropagation();
                    return false;
                }
            });
        });
    </script>
}

Here we load google api javascript file, run captcha rendering and attach a handler for validation response that we will use to send validation token to our back-end, validate it and return a new dynamic random URL for our <form> to submit data to.

Here is the server side controller action for reCAPTCHA validation:

        public ActionResult IsReCaptchValid(string gRecaptchaResponse)
        { //check referrer url to see if this request came from our own website
            if (Request.UrlReferrer == null || string.IsNullOrEmpty(Request.UrlReferrer.AbsolutePath) ||
                     !(Request.UrlReferrer.ToString().ToLowerInvariant().StartsWith(Extensions.Extensions.DomainName + "/contact") ||
                     Request.UrlReferrer.ToString().ToLowerInvariant().StartsWith(Extensions.Extensions.DomainName2 + "/contact")))
            {
                return HttpNotFound("Resource was not found");
            }
            string result = "none";
            var captchaResponse = gRecaptchaResponse;
            
            var apiUrl = "https://www.google.com/recaptcha/api/siteverify?secret={0}&response={1}";
            var requestUri = string.Format(apiUrl, secretKey, captchaResponse);
            var request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(requestUri);
            using (System.Net.WebResponse response = request.GetResponse())
            {
                using (System.IO.StreamReader stream = new System.IO.StreamReader(response.GetResponseStream()))
                {
                    JObject jResponse = JObject.Parse(stream.ReadToEnd());
                    var isSuccess = jResponse.Value<bool>("success");
                    if (isSuccess)
                    { //store token in session to re-validate later
                        Session["g-recaptcha-response"] = gRecaptchaResponse; //generate random url
                        result = "/Contact/" + 
                            ((char)rnd.Next(0x61, 0x7b)) + "" + //random char a-z
                            ((char)rnd.Next(0x61, 0x7b)) + "" +
                            ((char)rnd.Next(0x61, 0x7b)) + "" +
                            ((char)rnd.Next(0x61, 0x7b)) + "" +
                            ((char)rnd.Next(0x61, 0x7b)) + "" +
                            ((char)rnd.Next(0x61, 0x7b)) + "" +
                            ((char)rnd.Next(0x61, 0x7b)) + "" +
                            ((char)rnd.Next(0x61, 0x7b)) + "" ; //store the random url to validate later
                        Session["contactFormAction"] = result;
                    }
                }
            }
            return Content(result);
        }

As you may guessed this will validate google reCAPTCHA token and generate a random url like /Contact/edvbbgrq

Next step will be to accept POST request with all the data, validate and process it.
To be able to accept random urls like /Contact/edvbbgrq in one controller and one action you will have to define some routes, so lets define them now in our RouteConfig.cs:

            //route to accept /Contact/Contact get request and return our contact form/view
            routes.MapRoute(
                name: "Contact1",
                url: "Contact/Contact",
                defaults: new { controller = "Contact", action = "Contact" }
                ); //route to accept /Contact/IsReCaptchValid request and return our random urls
            routes.MapRoute(
                name: "Contact2",
                url: "Contact/IsReCaptchValid",
                defaults: new { controller = "Contact", action = "IsReCaptchValid" }
                ); //route to accept our random urls and submit contact requests
            routes.MapRoute(
                name: "CContact",
                url: "Contact/{*slug}",
                defaults: new { controller = "Contact", action = "CContact", slug = System.Web.Http.RouteParameter.Optional }
                );

And actually final step is implementing our POST action to accept random-url submit requests:

        //to return view Contact in Get and POSTback requests
        public ActionResult CContact(string slug = null)
        {
            return View("Contact");
        }
        [HttpPost]
        [ValidateAntiForgeryToken]
        public ActionResult CContact(string slug, string name, string subject, string message, string email)
        { //check if this request is from our own website
            if (Request.UrlReferrer == null || string.IsNullOrEmpty(Request.UrlReferrer.AbsolutePath) ||
                     !(Request.UrlReferrer.ToString().ToLowerInvariant().StartsWith(Extensions.Extensions.DomainName + "/contact") ||
                     Request.UrlReferrer.ToString().ToLowerInvariant().StartsWith(Extensions.Extensions.DomainName2 + "/contact")))
            {
                return HttpNotFound("Resource was not found");
            }
            //get previously stored random url
            string view = Session["contactFormAction"] as string;
            if (string.IsNullOrEmpty(view))
            {
                return HttpNotFound("Resource was not found");
            }
            view = view.Replace("/Contact/", string.Empty); //get random part from route to compare
            if(RouteData.GetRequiredString("slug") != view)
                return HttpNotFound("Resource was not found"); //just in case let's check the token one more time
            var captchaResponse = Request.Form["g-recaptcha-response"];
            if((string)Session["g-recaptcha-response"]!= captchaResponse)
            {
                return HttpNotFound("Resource was not found");
            }

            ... //do whatever you need to process request ...
            ViewBag.Message = "Thank you, your request has been submitted.";

            return View("Contact");
        }

That's it. Now you have dynamic action form url and this url is generated after human-validation only so it will be impossible or almost impossible at least  for spammers to send spam requests.

Thank you and see you :)



1vqHSTrq1GEoEF7QsL8dhmJfRMDVxhv2y



Get stack trace of frozen processes especially for asp.net application pools

There are so many times you need to get a place where your frozen process stuck aren't?

Especially if this is a production server or remote environment. So what to do?


I have faced this problem myself and created a small tool that gets stack trace from process by its name.

We will need the following instruments:

- Microsoft.Diagnostics.Runtime.dll

- System.Management.dll


And some code to find a process and get its stack trace.

        private string CatchStacktrace(string domainName)
        {
            int pid = -1;
            var procs = System.Diagnostics.Process.GetProcessesByName("w3wp");

            var proc = procs.FirstOrDefault(p => GetProcessOwner(p.Id).StartsWith(domainName));
            if (proc == null)
                return string.Format("User Name not found: {0}", domainName);

            pid = proc.Id;

            if (pid < 1)
                return string.Format("Process w3wp.exe not found: {0}", domainName);

            StringBuilder sb = new StringBuilder();
            sb.AppendLine(domainName);
            sb.AppendLine(string.Empty);

            using (var tdata = DataTarget.AttachToProcess(pid, 3000))
            {
                // Dump CLR info
                var clrVersion = tdata.ClrVersions.First();
                var dacInfo = clrVersion.DacInfo;

                sb.AppendLine("# CLR Info");
                sb.AppendLine(string.Format("Version:       {0}", clrVersion.Version));
                sb.AppendLine(string.Format("Filesize:      {0:X}", dacInfo.FileSize));
                sb.AppendLine(string.Format("Timestamp:     {0:X}", dacInfo.TimeStamp));
                sb.AppendLine(string.Format("Dac file:      {0}", dacInfo.FileName));

                sb.AppendLine(string.Empty);

                var runtime = clrVersion.CreateRuntime();
                var appDomain = runtime.AppDomains.First();

                sb.AppendLine(string.Format("# Runtime Info"));
                sb.AppendLine(string.Format("AppDomain:     {0}", appDomain.Name));
                sb.AppendLine(string.Format("Address:       {0}", appDomain.Address));
                sb.AppendLine(string.Format("Configuration: {0}", appDomain.ConfigurationFile));
                sb.AppendLine(string.Format("Directory:     {0}", appDomain.ApplicationBase));

                sb.AppendLine(string.Empty);

                // Dump thread info
                sb.AppendLine("## Threads");
                sb.AppendLine(string.Format("Thread count:  {0}", runtime.Threads.Count));
                sb.AppendLine(string.Empty);
                foreach (var thread in runtime.Threads)
                {
                    sb.AppendLine(string.Format("### Thread     {0}", thread.OSThreadId));
                    sb.AppendLine(string.Format("Thread type:   {0}",
                                            thread.IsBackground ? "Background"
                                          : thread.IsGC ? "GC"
                                          : "Foreground"));
                    var blocks = thread.BlockingObjects;
                    if (blocks != null)
                    {
                        foreach(var block in blocks)
                        {
                            sb.AppendLine(string.Format("Blocked by:  {0}   reason: {1}", block.ToString(), block.Reason.ToString()));
                        }
                    }

                    sb.AppendLine(string.Empty);
                    sb.AppendLine("Stack trace:");
                    foreach (var stackFrame in thread.EnumerateStackTrace())
                    {
                        sb.AppendLine(string.Format("* {0}", stackFrame.DisplayString));
                    }

                    sb.AppendLine(string.Empty);
                    sb.AppendLine(string.Empty);
                }
            }

            return sb.ToString();
        }

        string[] argList = new string[] { string.Empty, string.Empty };
        ManagementObjectCollection processList = null;
        ManagementObjectSearcher searcher = null;
        string query = "Select * From Win32_Process Where ProcessID = ";
        public string GetProcessOwner(int processId)
        {
            searcher = new ManagementObjectSearcher(query + processId);
            processList = searcher.Get();

            foreach (ManagementObject obj in processList)
            {
                argList[0] = string.Empty;
                argList[1] = string.Empty;
                int returnVal = Convert.ToInt32(obj.InvokeMethod("GetOwner", argList));
                if (returnVal == 0)
                {
                    return argList[0];
                }
            }

            return "NO OWNER";
        }


As you know asp.net applications all have w3wp process name and run under its own user name usually with the same name as website name. So to find w3wp process we will pass its username like "ok.unsode.com" to the CatchStacktrace method.

If appropriate w3wp process has been found then you will get something like that:



ok.unsode.com


# CLR Info

Version:       v4.7.2650.00

Filesize:      9E8000

Timestamp:     5AB1C520

Dac file:      mscordacwks_Amd64_Amd64_4.7.2650.00.dll


# Runtime Info

AppDomain:     DefaultDomain

Address:       2017397101184

Configuration: w3wp.exe.config

Directory:     c:\windows\system32\inetsrv\


## Threads

Thread count:  85


### Thread     8824

Thread type:   Background


Stack trace:



### Thread     7484

Thread type:   Background


Stack trace:

* DebuggerU2MCatchHandlerFrame



### Thread     9036

Thread type:   Background


Stack trace:



### Thread     7744

Thread type:   Background


Stack trace:



### Thread     13420

Thread type:   Background


Stack trace:



### Thread     6336

Thread type:   Background


Stack trace:

* System.Collections.Generic.Dictionary`2[[System.__Canon, mscorlib],[System.__Canon, mscorlib]].Insert(System.__Canon, System.__Canon, Boolean)

* MrCMS.Indexing.Management.GetLuceneIndexSearcher.Get(System.String)

* MrCMS.Indexing.Querying.Searcher`2[[System.__Canon, mscorlib],[System.__Canon, mscorlib]].Search(Lucene.Net.Search.Query, Int32, System.Nullable`1<Int32>, Lucene.Net.Search.Filter, Lucene.Net.Search.Sort)

* MrCMS.Web.Apps.Ecommerce.Services.Products.ProductSearchIndexService.SearchProducts(MrCMS.Web.Apps.Ecommerce.Models.ProductSearchQuery)

* MrCMS.Web.Apps.Ecommerce.Controllers.ProductSearchController.ProductsIndexSearch()

* DynamicClass.lambda_method(System.Runtime.CompilerServices.Closure, System.Web.Mvc.ControllerBase, System.Object[])

* System.Web.Mvc.ReflectedActionDescriptor.Execute(System.Web.Mvc.ControllerContext, System.Collections.Generic.IDictionary`2<System.String,System.Object>)

* System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(System.Web.Mvc.ControllerContext, System.Web.Mvc.ActionDescriptor, System.Collections.Generic.IDictionary`2<System.String,System.Object>)

* System.Web.Mvc.Async.AsyncControllerActionInvoker.<BeginInvokeSynchronousActionMethod>b__39(System.IAsyncResult, ActionInvocation)

* System.Web.Mvc.Async.AsyncResultWrapper+WrappedAsyncResult`2[[System.__Canon, mscorlib],[System.Web.Mvc.Async.AsyncControllerActionInvoker+ActionInvocation, System.Web.Mvc]].CallEndDelegate(System.IAsyncResult)

* System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(System.IAsyncResult)

* System.Web.Mvc.Async.AsyncControllerActionInvoker+AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3d()

* System.Web.Mvc.Async.AsyncControllerActionInvoker+AsyncInvocationWithFilters+<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()

* System.Web.Mvc.Async.AsyncControllerActionInvoker+AsyncInvocationWithFilters+<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()

* System.Web.Mvc.Async.AsyncControllerActionInvoker+AsyncInvocationWithFilters+<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()

* System.Web.Mvc.Async.AsyncControllerActionInvoker+AsyncInvocationWithFilters+<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()

* System.Web.Mvc.Async.AsyncControllerActionInvoker+AsyncInvocationWithFilters+<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()

* System.Web.Mvc.Async.AsyncControllerActionInvoker+AsyncInvocationWithFilters+<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()

* System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(System.IAsyncResult)

* System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass21+<>c__DisplayClass2b.<BeginInvokeAction>b__1c()

* System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass21.<BeginInvokeAction>b__1e(System.IAsyncResult)

* System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(System.IAsyncResult)

* System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(System.IAsyncResult, ExecuteCoreState)

* System.Web.Mvc.Async.AsyncResultWrapper+WrappedAsyncVoid`1[[System.Web.Mvc.Controller+ExecuteCoreState, System.Web.Mvc]].CallEndDelegate(System.IAsyncResult)

* System.Web.Mvc.Controller.EndExecuteCore(System.IAsyncResult)

* System.Web.Mvc.Async.AsyncResultWrapper+WrappedAsyncVoid`1[[System.__Canon, mscorlib]].CallEndDelegate(System.IAsyncResult)

* System.Web.Mvc.Controller.EndExecute(System.IAsyncResult)

* System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(System.IAsyncResult, ProcessRequestState)

* System.Web.Mvc.Async.AsyncResultWrapper+WrappedAsyncVoid`1[[System.Web.Mvc.MvcHandler+ProcessRequestState, System.Web.Mvc]].CallEndDelegate(System.IAsyncResult)

* System.Web.Mvc.MvcHandler.EndProcessRequest(System.IAsyncResult)

* System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerWrapper+<>c__DisplayClass4.<Wrap>b__3()

* System.Web.Mvc.HttpHandlerUtil+ServerExecuteHttpHandlerWrapper.Wrap[[System.__Canon, mscorlib]](System.Func`1<System.__Canon>)

* System.Web.HttpServerUtility.ExecuteInternal(System.Web.IHttpHandler, System.IO.TextWriter, Boolean, Boolean, System.Web.VirtualPath, System.Web.VirtualPath, System.String, System.Exception, System.String)

* System.Web.HttpServerUtility.Execute(System.Web.IHttpHandler, System.IO.TextWriter, Boolean, Boolean)

* System.Web.HttpServerUtility.Execute(System.Web.IHttpHandler, System.IO.TextWriter, Boolean)

* System.Web.Mvc.Html.ChildActionExtensions.ActionHelper(System.Web.Mvc.HtmlHelper, System.String, System.String, System.Web.Routing.RouteValueDictionary, System.IO.TextWriter)

* System.Web.Mvc.Html.ChildActionExtensions.RenderAction(System.Web.Mvc.HtmlHelper, System.String, System.String)

* ASP._Page_Apps_Core_Views_Shared__BaseLayout_cshtml.Execute()

* System.Web.WebPages.WebPageBase.ExecutePageHierarchy()

* System.Web.Mvc.WebViewPage.ExecutePageHierarchy()

* System.Web.WebPages.WebPageBase.ExecutePageHierarchy(System.Web.WebPages.WebPageContext, System.IO.TextWriter, System.Web.WebPages.WebPageRenderingBase)

* System.Web.WebPages.WebPageBase+<>c__DisplayClass3.<RenderPageCore>b__2(System.IO.TextWriter)

* System.Web.WebPages.WebPageBase.Write(System.Web.WebPages.HelperResult)

* System.Web.WebPages.WebPageBase.RenderSurrounding(System.String, System.Action`1<System.IO.TextWriter>)

* System.Web.WebPages.WebPageBase.PopContext()

* System.Web.Mvc.ViewResultBase.ExecuteResult(System.Web.Mvc.ControllerContext)

* System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(System.Collections.Generic.IList`1<System.Web.Mvc.IResultFilter>, Int32, System.Web.Mvc.ResultExecutingContext, System.Web.Mvc.ControllerContext, System.Web.Mvc.ActionResult)

* System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(System.Collections.Generic.IList`1<System.Web.Mvc.IResultFilter>, Int32, System.Web.Mvc.ResultExecutingContext, System.Web.Mvc.ControllerContext, System.Web.Mvc.ActionResult)

* System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(System.Collections.Generic.IList`1<System.Web.Mvc.IResultFilter>, Int32, System.Web.Mvc.ResultExecutingContext, System.Web.Mvc.ControllerContext, System.Web.Mvc.ActionResult)

* System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(System.Collections.Generic.IList`1<System.Web.Mvc.IResultFilter>, Int32, System.Web.Mvc.ResultExecutingContext, System.Web.Mvc.ControllerContext, System.Web.Mvc.ActionResult)

* System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(System.Collections.Generic.IList`1<System.Web.Mvc.IResultFilter>, Int32, System.Web.Mvc.ResultExecutingContext, System.Web.Mvc.ControllerContext, System.Web.Mvc.ActionResult)

* System.Web.Mvc.ControllerActionInvoker.InvokeActionResultFilterRecursive(System.Collections.Generic.IList`1<System.Web.Mvc.IResultFilter>, Int32, System.Web.Mvc.ResultExecutingContext, System.Web.Mvc.ControllerContext, System.Web.Mvc.ActionResult)

* System.Web.Mvc.ControllerActionInvoker.InvokeActionResultWithFilters(System.Web.Mvc.ControllerContext, System.Collections.Generic.IList`1<System.Web.Mvc.IResultFilter>, System.Web.Mvc.ActionResult)

* System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass21.<BeginInvokeAction>b__1e(System.IAsyncResult)

* System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(System.IAsyncResult)

* System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(System.IAsyncResult, ExecuteCoreState)

* System.Web.Mvc.Async.AsyncResultWrapper+WrappedAsyncVoid`1[[System.Web.Mvc.Controller+ExecuteCoreState, System.Web.Mvc]].CallEndDelegate(System.IAsyncResult)

* System.Web.Mvc.Controller.EndExecuteCore(System.IAsyncResult)

* System.Web.Mvc.Async.AsyncResultWrapper+WrappedAsyncVoid`1[[System.__Canon, mscorlib]].CallEndDelegate(System.IAsyncResult)

* System.Web.Mvc.Controller.EndExecute(System.IAsyncResult)

* System.Web.Mvc.Async.AsyncResultWrapper+WrappedAsyncResultBase`1[[System.Web.Mvc.Async.AsyncVoid, System.Web.Mvc]].Begin(System.AsyncCallback, System.Object, Int32)

* System.Web.Mvc.Controller.BeginExecute(System.Web.Routing.RequestContext, System.AsyncCallback, System.Object)

* MrCMS.Website.Routing.MrCMSStandardRouteHandler.Handle(System.Web.Routing.RequestContext)

* MrCMS.Website.Routing.MrCMSHttpHandler.ProcessRequest(System.Web.Routing.RequestContext)

* System.Web.HttpApplication+CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()

* System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep)

* System.Web.HttpApplication.ExecuteStep(IExecutionStep, Boolean ByRef)

* System.Web.HttpApplication+PipelineStepManager.ResumeSteps(System.Exception)

* System.Web.HttpApplication.BeginProcessRequestNotification(System.Web.HttpContext, System.AsyncCallback)

* System.Web.HttpRuntime.ProcessRequestNotificationPrivate(System.Web.Hosting.IIS7WorkerRequest, System.Web.HttpContext)

* System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr, IntPtr, IntPtr, Int32)

* System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr, IntPtr, IntPtr, Int32)

* DomainNeutralILStubClass.IL_STUB_ReversePInvoke(Int64, Int64, Int64, Int32)

* InlinedCallFrame

* InlinedCallFrame

* DomainNeutralILStubClass.IL_STUB_PInvoke(IntPtr, System.Web.RequestNotificationStatus ByRef)

* System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr, IntPtr, IntPtr, Int32)

* System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr, IntPtr, IntPtr, Int32)

* DomainNeutralILStubClass.IL_STUB_ReversePInvoke(Int64, Int64, Int64, Int32)

* ContextTransitionFrame



### Thread     9976

Thread type:   Background


Stack trace:



### Thread     11760

Thread type:   Background


Stack trace:



### Thread     6112

Thread type:   Background


Stack trace:



### Thread     0

Thread type:   Foreground


Stack trace:



### Thread     0

Thread type:   Foreground


Stack trace:



### Thread     0

Thread type:   Foreground


Stack trace:



### Thread     0

Thread type:   Foreground


Stack trace:



### Thread     0

Thread type:   Foreground


Stack trace:



### Thread     0

Thread type:   Foreground


Stack trace:



### Thread     0

Thread type:   Foreground


Stack trace:



### Thread     0

Thread type:   Foreground


Stack trace:



### Thread     0

Thread type:   Foreground


Stack trace:



### Thread     0

Thread type:   Foreground


Stack trace:



### Thread     0

Thread type:   Foreground


Stack trace:



### Thread     0

Thread type:   Foreground


Stack trace:



### Thread     16772

Thread type:   Background


Stack trace:



### Thread     0

Thread type:   Foreground


Stack trace:



### Thread     0

Thread type:   Foreground


Stack trace:



### Thread     0

Thread type:   Foreground


Stack trace:



### Thread     0

Thread type:   Foreground


Stack trace:



### Thread     0

Thread type:   Foreground


Stack trace:



### Thread     8280

Thread type:   Background


Stack trace:



### Thread     12476

Thread type:   Background


Stack trace:

* System.Collections.Generic.Dictionary`2[[System.__Canon, mscorlib],[System.__Canon, mscorlib]].Remove(System.__Canon)

* MrCMS.Indexing.Management.GetLuceneIndexSearcher.Reset(System.String)

* MrCMS.Indexing.Management.IndexManager`2[[System.__Canon, mscorlib],[System.__Canon, mscorlib]].<Optimise>b__35_0()

* MrCMS.Indexing.Management.IndexResult.GetResult(System.Action)

* MrCMS.Tasks.OptimiseIndexesController.Execute(System.String)

* DynamicClass.lambda_method(System.Runtime.CompilerServices.Closure, System.Web.Mvc.ControllerBase, System.Object[])

* System.Web.Mvc.ReflectedActionDescriptor.Execute(System.Web.Mvc.ControllerContext, System.Collections.Generic.IDictionary`2<System.String,System.Object>)

* System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(System.Web.Mvc.ControllerContext, System.Web.Mvc.ActionDescriptor, System.Collections.Generic.IDictionary`2<System.String,System.Object>)

* System.Web.Mvc.Async.AsyncControllerActionInvoker.<BeginInvokeSynchronousActionMethod>b__39(System.IAsyncResult, ActionInvocation)

* System.Web.Mvc.Async.AsyncResultWrapper+WrappedAsyncResult`2[[System.__Canon, mscorlib],[System.Web.Mvc.Async.AsyncControllerActionInvoker+ActionInvocation, System.Web.Mvc]].CallEndDelegate(System.IAsyncResult)

* System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(System.IAsyncResult)

* System.Web.Mvc.Async.AsyncControllerActionInvoker+AsyncInvocationWithFilters.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3d()

* System.Web.Mvc.Async.AsyncControllerActionInvoker+AsyncInvocationWithFilters+<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()

* System.Web.Mvc.Async.AsyncControllerActionInvoker+AsyncInvocationWithFilters+<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()

* System.Web.Mvc.Async.AsyncControllerActionInvoker+AsyncInvocationWithFilters+<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()

* System.Web.Mvc.Async.AsyncControllerActionInvoker+AsyncInvocationWithFilters+<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()

* System.Web.Mvc.Async.AsyncControllerActionInvoker+AsyncInvocationWithFilters+<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()

* System.Web.Mvc.Async.AsyncControllerActionInvoker+AsyncInvocationWithFilters+<>c__DisplayClass46.<InvokeActionMethodFilterAsynchronouslyRecursive>b__3f()

* System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(System.IAsyncResult)

* System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass21+<>c__DisplayClass2b.<BeginInvokeAction>b__1c()

* System.Web.Mvc.Async.AsyncControllerActionInvoker+<>c__DisplayClass21.<BeginInvokeAction>b__1e(System.IAsyncResult)

* System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(System.IAsyncResult)

* System.Web.Mvc.Controller.<BeginExecuteCore>b__1d(System.IAsyncResult, ExecuteCoreState)

* System.Web.Mvc.Async.AsyncResultWrapper+WrappedAsyncVoid`1[[System.Web.Mvc.Controller+ExecuteCoreState, System.Web.Mvc]].CallEndDelegate(System.IAsyncResult)

* System.Web.Mvc.Controller.EndExecuteCore(System.IAsyncResult)

* System.Web.Mvc.Async.AsyncResultWrapper+WrappedAsyncVoid`1[[System.__Canon, mscorlib]].CallEndDelegate(System.IAsyncResult)

* System.Web.Mvc.Controller.EndExecute(System.IAsyncResult)

* System.Web.Mvc.MvcHandler.<BeginProcessRequest>b__5(System.IAsyncResult, ProcessRequestState)

* System.Web.Mvc.Async.AsyncResultWrapper+WrappedAsyncVoid`1[[System.Web.Mvc.MvcHandler+ProcessRequestState, System.Web.Mvc]].CallEndDelegate(System.IAsyncResult)

* System.Web.Mvc.MvcHandler.EndProcessRequest(System.IAsyncResult)

* System.Web.HttpApplication+CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()

* System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep)

* System.Web.HttpApplication.ExecuteStep(IExecutionStep, Boolean ByRef)

* System.Web.HttpApplication+PipelineStepManager.ResumeSteps(System.Exception)

* System.Web.HttpApplication.BeginProcessRequestNotification(System.Web.HttpContext, System.AsyncCallback)

* System.Web.HttpRuntime.ProcessRequestNotificationPrivate(System.Web.Hosting.IIS7WorkerRequest, System.Web.HttpContext)

* System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr, IntPtr, IntPtr, Int32)

* System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr, IntPtr, IntPtr, Int32)

* DomainNeutralILStubClass.IL_STUB_ReversePInvoke(Int64, Int64, Int64, Int32)

* InlinedCallFrame

* InlinedCallFrame

* DomainNeutralILStubClass.IL_STUB_PInvoke(IntPtr, System.Web.RequestNotificationStatus ByRef)

* System.Web.Hosting.PipelineRuntime.ProcessRequestNotificationHelper(IntPtr, IntPtr, IntPtr, Int32)

* System.Web.Hosting.PipelineRuntime.ProcessRequestNotification(IntPtr, IntPtr, IntPtr, Int32)

* DomainNeutralILStubClass.IL_STUB_ReversePInvoke(Int64, Int64, Int64, Int32)

* ContextTransitionFrame



### Thread     10172

Thread type:   Background


Stack trace:



### Thread     14028

Thread type:   Background


Stack trace:



### Thread     10924

Thread type:   Background


Stack trace:



### Thread     0

Thread type:   Foreground


Stack trace:



### Thread     0

Thread type:   Foreground


Stack trace:



### Thread     0

Thread type:   Foreground


Stack trace:



### Thread     0

Thread type:   Foreground


Stack trace:



### Thread     0

Thread type:   Foreground


Stack trace:



### Thread     0

Thread type:   Foreground


Stack trace:



### Thread     0

Thread type:   Foreground


Stack trace:



### Thread     0

Thread type:   Foreground


Stack trace:



### Thread     0

Thread type:   Foreground


Stack trace:



### Thread     8412

Thread type:   Background


Stack trace:





Hope it will help you and makes your life much easier :) You can easily change it to debug any process.


Thank you


1vqHSTrq1GEoEF7QsL8dhmJfRMDVxhv2y