NopCommerce 3.8 - Wait Operation Timeout

· 1 min

Developing NopCommerce locally against a test database, I've seen SQL queries take a long time to resolve. The larger your seed or test dataset, the worse it gets.

Logging into the administration area, I'd frequently get this error, despite a high connection timeout:

Exception Details: System.ComponentModel.Win32Exception: The wait operation timed out
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[Win32Exception (0x80004005): The wait operation timed out]

The stack trace pointed to PagedList.cs, at a method working on an IQueryable from a DbSet. The admin dashboard performs a lot of reads when it first loads, and those are the main cause of the timeouts.

Solution

All the dashboard statistics calls are in a single view, Nop.Admin/Views/Home/Index.cshtml.

To skip them on your machine, wrap them in an if on HttpContext.Current.IsDebuggingEnabled:

<div class="content">
    <div class="row">
        <div class="col-md-12">

            @if (!HttpContext.Current.IsDebuggingEnabled)
            {
                @Html.Widget("admin_dashboard_top")
                if (!Model.IsLoggedInAsVendor)
                {
                    <div class="row">
                        <div class="col-md-12">
                            @Html.Action("NopCommerceNews", "Home")
                        </div>
                    </div>
                }
                @Html.Widget("admin_dashboard_news_after")
                if (!Model.IsLoggedInAsVendor && canManageOrders && canManageCustomers && canManageProducts && canManageReturnRequests)
                {
                    <div class="row">
                        <div class="col-md-12">
                            @Html.Action("CommonStatistics", "Home")
                        </div>
                    </div>
                }
                @Html.Widget("admin_dashboard_commonstatistics_after")
                if (!Model.IsLoggedInAsVendor && (canManageOrders || canManageCustomers))
                {
                    <div class="row">
                        @if (!Model.IsLoggedInAsVendor && canManageOrders)
                        {
                            <div class="col-md-6">
                                @Html.Action("OrderStatistics", "Order")
                            </div>
                        }
                        @if (!Model.IsLoggedInAsVendor && canManageCustomers)
                        {
                            <div class="col-md-6">
                                @Html.Action("CustomerStatistics", "Customer")
                            </div>
                        }
                    </div>
                }
                @Html.Widget("admin_dashboard_customerordercharts_after")
                if (!Model.IsLoggedInAsVendor && canManageOrders)
                {
                    <div class="row">
                        <div class="col-md-8">
                            @Html.Action("OrderAverageReport", "Order")
                        </div>
                        <div class="col-md-4">
                            @Html.Action("OrderIncompleteReport", "Order")
                        </div>
                    </div>
                }
                @Html.Widget("admin_dashboard_orderreports_after")
                if (!Model.IsLoggedInAsVendor && (canManageOrders || canManageProducts))
                {
                    <div class="row">
                        @if (canManageOrders)
                        {
                            <div class="col-md-8">
                                @Html.Action("LatestOrders", "Order")
                            </div>
                        }
                        <div class="col-md-4">
                            @if (canManageProducts)
                            {
                                @Html.Action("PopularSearchTermsReport", "Common")
                            }
                        </div>
                    </div>
                }
                @Html.Widget("admin_dashboard_latestorders_searchterms_after")
                if (canManageOrders)
                {
                    <div class="row">
                        <div class="col-md-6">
                            @Html.Action("BestsellersBriefReportByQuantity", "Order")
                        </div>
                        <div class="col-md-6">
                            @Html.Action("BestsellersBriefReportByAmount", "Order")
                        </div>
                    </div>
                }
                @Html.Widget("admin_dashboard_bottom")
            }

        </div>
    </div>
</div>

Depending on your project, you may want something more robust, but for local debugging this is perfectly fine.