I am running VS 2012 (Update 2) / .NET 4.5 / IIS Express 8.0 / Win 7 on my dev box. I am using async WebAPI (not web api 2) controllers.
Of late, I started noticing that when running the web api project with the VS debugger attached, I am getting intermittent "Thread was being aborted" errors. I had made some changes to Visual Studio recently and my knee jerk reaction was that was the cause of the issue.
I spent some time digging a bit deeper and I noticed that on inspecting the exception object, all the properties have the following error, "Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack." The error happens at different parts of the code when stepping through the code as is indicated in Rick Strahl's post:
This SO post
suggests that it might be indicative of starting a backgound task using Task.Factory.StartNew
Is it correct/safe to use Task.Factory.StartNew
in a web application ?
Could it cause any issues (such as killing of the background task perhaps when running in a hosted process such as ASP.NET).
Most of the operation are CRUD style operations and are not long running per se.
Also, this issue has not yet happened when running normally(without debugger attached) in IIS express / IIS 7.5.
Below is a code snippet that captures the essence of the nature of processing and the structure of the async controller.
Any insights would be much appreciated.
public class SomeClass
{
private Lazy<string> str;
public SomeClass()
{
str = new Lazy<string>(Init);
}
private string Init()
{
try
{
string s = "whatever";
return s;
}
catch (Exception ex)
{
throw ex;
}
}
private string GetInternalString()
{
return str.Value;
}
public Task<string> GetString()
{
return Task.Factory.StartNew(() => GetInternalString());
}
}
public class TestController : ApiController
{
private async Task<string> GetStringAsync()
{
SomeClass c = new SomeClass();
var x = await c.GetString();
return x;
}
public async Task<string> Get(int id)
{
string s = await GetStringAsync();
return s;
}
}
UPDATE:
I believe I figured out the problem(code sample updated). While debugging I added str.Value
to the Watch widow AND set a breakpoint on string s = "whatever";
On Single stepping through the code I was able to repro the problem.
Removing the str.Value
from the watch window causes the issue to go away.
I think this is related to the explanation given in this SO post
and the debugger is killing the thread to avoid a deadlock. I just need to validation that this is the case and not a true coding error related to the use of Task.Factory.StartNew