Reputation: 1389
I have a multi-threaded environment in .NET that needs to communicate to a library. The library has some limitations and therefore cannot work correctly with multi-threaded environments. I need a way to solve this issue by making middle layer that the multi-threaded environment communicates with and then calls the library. I made a solution that solved the problem but I am not convinced that it is the best one. I created an asynchronous thread that has a run method. The run method is in infinite loop that checks what is the current task (a parameter that I set) and executes the corresponding method.
As I said, I am not convinced at all with this solution but it does the job correctly. So please inform me if there is a better one to solve it (especially if it is related to C#).
Just as a side note, the limitation isn't due to multiple threads that are working at the same time and causing data corruption. I need the exact same thread to do everything (depends on thread id).
Upvotes: 2
Views: 1145
Reputation: 217401
Have a look at the Task Parallel Library.
I recommend you implement a custom TaskScheduler that schedules all tasks on the same thread. You can use the scheduler to schedule a Task (no result value) or a Task<T> (result of type T).
You can use a BlockingCollection<Task> wrapping a ConcurrentQueue<Task> to implement the scheduler.
For example, assuming that your library exposes a function MakeCoffee, you could create a class CoffeeMachine that provides a matching wrapper method and schedules the task of calling the library on the custom scheduler:
public class CoffeeMachine
{
private readonly TaskScheduler scheduler;
public CoffeeMachine()
{
this.scheduler = new SingleThreadTaskScheduler();
}
public Task<Coffee> MakeCoffeeAsync()
{
return Task.Factory.StartNew<Coffee>(
this.MakeCoffee,
CancellationToken.None,
TaskCreationOptions.None,
this.scheduler);
}
private Coffee MakeCoffee()
{
// this method will always execute on the same thread
}
}
Usage:
CoffeeMachine machine = new CoffeeMachine();
Task<Coffee> task = machine.MakeCoffeeAsync(); // start task
task.Wait(); // wait for task to complete
Drink(task.Result); // use result
Upvotes: 2