user9046719
user9046719

Reputation:

null: System.Web.HttpContext.Current.Response; when using threads

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

Answers (1)

SLaks
SLaks

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

Related Questions