Reputation: 38
I have one async method that do multiple async tasks. And, I'm trying to call it more than once at the same time and each time it gets called and fails due to concurrency issue it recalls itself otherwise it finishes execution.
This task is also using a static variable and to be able to make this variable thread-safe since each of them has their own instance of this variable, I made it [ThreadStatic].
The following code will demonstrate what I mean: -
public class Program
{
[ThreadStatic]
private static Account _account;
public static async Task Main()
{
await Task.WhenAll(Enumerable.Repeat(Func, 5).Select(func => Task.Factory.StartNew(func).Unwrap()).ToArray());
}
public static async Task Func()
{
try
{
// Doing multiple async tasks
}
catch
{
// If catches concurrency issue, try again
await Func()
}
}
}
My problem is that if the task failed and recalled itself, it'd recall itself in another thread, hence doesn't have access to the same instance of the static variable.
So, how can I achieve this so that all recursive calls get the same value of the static variable ?
Upvotes: 0
Views: 241
Reputation: 456322
The best solution is to get rid of the ThreadStatic
variable completely. You may be able to replace it with an AsyncLocal<T>
.
If you absolutely cannot modify that code, then you can do a really dirty trick by temporarily seizing control of the thread pool threads and installing a single-threaded synchronization context on them, e.g., using AsyncContext
from my AsyncEx library:
public static void Main()
{
Parallel.ForEach(Enumerable.Repeat(Func, 5),
func => AsyncContext.Run(func));
}
But seriously, I wouldn't. Just change the ThreadStatic
variable instead.
Upvotes: 2