2

I have a website, there is a method like this:

public Context GetContext()
{
 ...
}

This method will be called several times when a user login to the website, and the method will return some information.

Now I have an other thread start by the website, the thread will do something. And the in the thread job this method also will be called several times.

The problem is, in these two situation, the method should return different result, for some reason I can't use another method or add parameters to the method.

Is there anyway to identify the current thread in a method? Basically, I want to archive something like this:

var thread = new Thread(GetContext);
thread.SomeFlag = True.
thread.Start()

public Context GetContext()
{
   Var thread = GetCurrentThread();
   If(thread.SomeFlag == True)
      //do some thing...
   Else
      //do some thing...
}

Is that possible?

Jarvan
  • 1,135
  • 8
  • 22
  • 2
    Try `System.Threading.Thread.CurrentThread.ManagedThreadId`. – Enigmativity Sep 19 '17 at 07:14
  • 5
    Explicitly running other threads within an asp.net application is almost always the wrong solution to a perceived problem. If we knew what *problem* you were trying to solve by running this other thread, we may be able to offer decent solutions. – Damien_The_Unbeliever Sep 19 '17 at 07:19
  • @Damien_The_Unbeliever is there anyway can avoid running other threads to running a background task in asp.net? – Jarvan Sep 19 '17 at 08:04
  • 1
    I can't speak for your results, but when I search `Background Tasks ASP.NET`, [this](https://www.hanselman.com/blog/HowToRunBackgroundTasksInASPNET.aspx) is my first result, which discusses (and links to) why its bad to use threads *and* discusses viable alternatives. – Damien_The_Unbeliever Sep 19 '17 at 08:06
  • Yeah, I did read the link before i post this topic. But I don't see any difference between using a naive thread and using Task, QueueBackgroundWorkItem or something else. They all using thread, right? – Jarvan Sep 19 '17 at 08:16
  • Check this [out](https://stackoverflow.com/questions/1679243/getting-the-thread-id-from-a-thread/1679269#1679269) there are enough information and examples. – Masoud Andalibi Sep 19 '17 at 08:31
  • 1
    @jarvanJiang: No! Tasks and Threads are not the same. There is no affinity between Tasks and Threads. A Task may or may not spin up a new thread and it may jump between threads. You should not spin up new threads in ASP.NET to execute CPU heavy things. But it may be a good idea to use async Tasks for non-CPU heavy stuff such as accessing a database (on another server) or doing I/O file stuff because Windows can do that asynchronously. But if you start threads on your own you are stealing threads from your webserver which won't scale well. – Jakob Christensen Sep 19 '17 at 08:39
  • 1
    QueueBackgroundWorkItem is different because you're *letting the ASP.Net runtime actually know about this background task*, so it will try to accommodate it and e.g. not decide to kill the current appdomain whilst it's still running. – Damien_The_Unbeliever Sep 19 '17 at 08:48
  • Thanks for explaination Jakob and Damien, i have learn a lot. But in my situation, I open a new thread when application_start, so I can guarantee there will be only one extra thread. If so, are task or QueueBackgroundWorkItem more effective than nave thread? – Jarvan Sep 19 '17 at 09:09

1 Answers1

2

You can use the ThreadStaticAttribute to set the value of a field individually for each thread. You set the value at the beginning of each thread (you can not set it outside the thread) and evaluate it within:

[ThreadStatic]
private static bool someFlag;

var thread = new Thread(GetContext);
thread.Start()

public Context GetContext()
{
   someFlag = true;
   //...
   if(someFlag == true)
      //do some thing...
   else
      //do some thing...
}

That allows you to store arbitrary data for each thread. Unlike with a thread ID, you have full control over the data you want to store.

Sefe
  • 13,731
  • 5
  • 42
  • 55
  • 1
    Since `someFlag` is static, `thread.SomeFlag` makes no sense. – Jakob Christensen Sep 19 '17 at 07:50
  • Sounds good. Just one question, is this attribute behavior the same in different classes? e.g. put this threadstatic variable to another class(may be static or not). – Jarvan Sep 19 '17 at 07:52
  • @JakobChristensen: as someFlag has the ThreadStatic attribute applied a unique static flag is created per Thread : see https://msdn.microsoft.com/en-us/library/system.threadstaticattribute.aspx – PaulF Sep 19 '17 at 07:59
  • @PaulF: I understand that but `thead.SomeFlag` is only valid for instance members and not static members. You would have to use `Thead.someFlag` in the above example instead. – Jakob Christensen Sep 19 '17 at 08:11
  • @jarvanJiang: You can use `TheadStatic` on any static property in any class. They will all store state local to the thread. But `ThreadStatic` can only be used on static fields and not instance fields. – Jakob Christensen Sep 19 '17 at 08:13
  • The field might be static, but it is static *to the thread*. In effect, this is not per instance and not static either. It is per thread, which effectively makes it per thread instance. – Sefe Sep 19 '17 at 08:16
  • @JakobChristensen: I see now - your meaning was not immediately obvious from your comment. – PaulF Sep 19 '17 at 08:18
  • @Sefe: That is true and I see that you have fixed your code so that it is now correct. – Jakob Christensen Sep 19 '17 at 08:34