Reputation:
I have a numebr of threads (let's just say 2 for now). from inside them, I am accessing a function named ExportCSVSingle(string mac)
what this does is, it creates a .csv
file for a specific thread. but it crashes at the var response = System.Web.HttpContext.Current.Response;
saying response is null
. The code works fine if I use it without threads. I tried using the mutex locking
which I already was when storing it in the db, but it did not work.
I will post only the relevant and short code below:
[HttpGet]
public ActionResult GetCloudDevices()
{
var macList = db.Mac.ToList();
foreach (var g in macList)
{
Thread createComAndMessagePumpThread = new Thread(() =>
{
if (isConnected)
{
mutex.WaitOne();
//...
db.SaveChanges();
//CSVmutex.WaitOne();
ExportDailyCSV(g.Mac);
//CSVmutex.ReleaseMutex();
//where g.Mac is a string like abc-1-1
...// } mutex.ReleaseMutex();
Now the function:
public void ExportDailyCSV(string machine)
{
//CSVmutex.WaitOne();
var sb = new StringBuilder();
var list = (from o in db.Logs
where o.Machine == machine && o.sDate == DateTime.Today
select o).ToList();
var fileName = machine;
sb.AppendFormat("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10}", "No", "Name", "Time", "Mode", "Mac", "Ex", "type", "sid", "work", "sDate", Environment.NewLine);
foreach (var item in list)
{
sb.AppendFormat("{0},{1},{2},{3},{4},{5},{6},{7},{8},{9},{10}", item.No, item.Name, item.Time, item.Mode, item.Mac, item.Ex, item.Type, item.SId, item.Work, item.Date.Value.ToShortDateString(), Environment.NewLine);
}
try
{
//Get Current Response this is where it throws the exception
var response = System.Web.HttpContext.Current.Response;
response.BufferOutput = true;
response.Clear();
response.ClearHeaders();
response.ContentEncoding = Encoding.Unicode;
response.ContentEncoding = Encoding.Default;
//response.AddHeader("content-disposition", string.Format("attachment;filename={0}.csv", fileName));
//response.AddHeader("content-disposition", fileDetail);
var attachmentValue = string.Format("attachment;filename={0}.csv", fileName);
response.AddHeader("content-disposition", attachmentValue);
response.ContentType = "text/csv";
response.Write(sb.ToString());
response.End();
}
catch (ArgumentNullException ex)
{
Response.Write("Property: " + ex.ParamName + " Error: " + ex.Message);
}
//CSVmutex.ReleaseMutex();
}
Upvotes: 0
Views: 1492
Reputation: 887777
You cannot access HttpContext.Current
from any other thread (what if there are two requests at once?)
You should rewrite your code to separate your data logic from the HTTP response.
Specifically, you should move all of the data logic to a standalone function that returns Task<T>
(use TaskCompletionSource<T>
to set its result from the other thread).
Your controller action should then await
that task and put its result in an ActionResult
.
Upvotes: 2