Home > Back-end >  Why am I getting a NullReferenceException only on the LiveServer in this Async operation?
Why am I getting a NullReferenceException only on the LiveServer in this Async operation?

Time:12-20

This is an intermitted issue, when I tried to post this live.

protected void searchasync(string search, string usproengineer_id)
{
    Task a = Task.Run(() => searchuasync(search, usproengineer_id));
    Task b = Task.Run(() => searchcasync(search, usproengineer_id));
    Task c = Task.Run(() => searchpasync(search, usproengineer_id));
    Task.WaitAll(a, b, c);
}

Then each subsequent search section has:

protected async void searchuasync(string search, string usproengineer_id)
{
    Task<DataTable> taskAU = Task.Run(() => searchUinjection(search, usproengineer_id));
    Task<DataTable> taskBU = Task.Run(() => searchUexpinjection(search, usproengineer_id));
    Task<DataTable> taskCU = Task.Run(() => searchUcncinjection(search, usproengineer_id));
    Task<DataTable> taskDU = Task.Run(() => searchUcncmetalinjection(search, usproengineer_id));
    Task<DataTable> taskEU = Task.Run(() => searchUurethaneinjection(search, usproengineer_id));
    Task.WaitAll(taskAU, taskBU, taskCU, taskDU, taskEU); //Wait till these parts are done
    ....

So this code has no problem on my local in the Debugger running. Or on the Test-Server which is "Almost" the same as the live-server. That is, I have no problem running the threaded searches. But I did not anticipate receiving this error multiple times that I can't explain:

Exception: System.NullReferenceException
Message: Object reference not set to an instance of an object.

StackTrace:    at USAProEngHome.<searchcasync>d__1b.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.AsyncMethodBuilderCore.<>c.<ThrowAsync>b__6_1(Object state)
   at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
   at System.Threading.ThreadPoolWorkQueue.Dispatch()
   at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()

This does seem to be related to this StackOverFlow But not quite the same. I have the webconfig targetframework set to 4.6 and no legacy set. It is possible I have something misconfigured in my webconfig but don't know what it is.

CodePudding user response:

So here is my own answer to the question and what seemed to fix it (maybe someone could still point out ways to improve the design speed...): Notice above I had '...' in Searchuasync (as I didn't show the rest of the code). Now, I had moved that code to its parent 'Searchasync'.
So now the SearchUasync looks like the following: (returning a Datatable.. Each of the 3 functions look like this, and they each have subsequent tasks that run asynchronously)

 protected async Task<DataTable> searchuasync(string search, string usproengineer_id)
{
    Task<DataTable> taskAU = Task.Run(() => searchUinjection(search, usproengineer_id));
    Task<DataTable> taskBU = Task.Run(() => searchUexpinjection(search, usproengineer_id));
    Task<DataTable> taskCU = Task.Run(() => searchUcncinjection(search, usproengineer_id));
    Task<DataTable> taskDU = Task.Run(() => searchUcncmetalinjection(search, usproengineer_id));
    Task<DataTable> taskEU = Task.Run(() => searchUurethaneinjection(search, usproengineer_id));
    Task.WaitAll(taskAU, taskBU, taskCU, taskDU, taskEU);
    //Unconfirmed query...
    DataTable dt6 = await taskAU;
    DataTable dt7 = await taskBU;
    DataTable dt8 = await taskCU;
    DataTable dt9 = await taskDU;
    DataTable dt10 = await taskEU;
    dt6.Merge(dt7, true, MissingSchemaAction.Ignore);
    dt6.Merge(dt8, true, MissingSchemaAction.Ignore);
    dt6.Merge(dt9, true, MissingSchemaAction.Ignore);
    dt6.Merge(dt10, true, MissingSchemaAction.Ignore);

    return dt6;
}

Then in the parent looks like this: (notice I've commented out the original task.waitall command, and I'm just using an 'await' for each of the 3 parts. Thinking the 'await c' is the most expensive. By the time it gets to 'await a' or 'b' they should be done. But maybe not in every case.

protected async void searchasync(string search, string usproengineer_id)
{
    Task<DataTable> c = Task.Run(() => searchpasync(search, usproengineer_id));
    Task<DataTable> b = Task.Run(() => searchcasync(search, usproengineer_id));
    Task<DataTable> a = Task.Run(() => searchuasync(search, usproengineer_id));
    //Task.WaitAll(a, b, c);

    DataTable dt1 = await c;
    ((GridView)ContentPlaceHolder1.FindControl("GridView_MoldProjects")).DataSource = dt1;
    ContentPlaceHolder1.FindControl("GridView_MoldProjects").DataBind();
    if (dt1.Rows.Count != 0)
    {
        ((HtmlInputHidden)ContentPlaceHolder1.FindControl("hidden_4")).Value = "1";
    }
    else
    {
        ((HtmlInputHidden)ContentPlaceHolder1.FindControl("hidden_4")).Value = "0";
    }

    DataTable dt11 = await b;
    ((GridView)ContentPlaceHolder1.FindControl("GridView_ConfirmedQuotes")).DataSource = dt11;
    ContentPlaceHolder1.FindControl("GridView_ConfirmedQuotes").DataBind();
    if (dt11.Rows.Count != 0)
    {
        ((HtmlInputHidden)ContentPlaceHolder1.FindControl("hidden_2")).Value = "1";
    }
    else
    {
        ((HtmlInputHidden)ContentPlaceHolder1.FindControl("hidden_2")).Value = "0";
    }
    //end confirm3ed

    DataTable dt6 = await a;
    ((GridView)ContentPlaceHolder1.FindControl("GridView_UnconfirmedQuotes")).DataSource = dt6;
    ContentPlaceHolder1.FindControl("GridView_UnconfirmedQuotes").DataBind();
    if (dt6.Rows.Count != 0)
    {
        ((HtmlInputHidden)ContentPlaceHolder1.FindControl("hidden_1")).Value = "1";
    }
    else
    {
        ((HtmlInputHidden)ContentPlaceHolder1.FindControl("hidden_1")).Value = "0";
    }
    //End Unconfirmed

}

I've seen no evidence of the 'nullreference' compiler generated Async error. It's been live-tested this way for one-day. With numerous hits.

  • Related