I have a class wich performs some data processing:
class Processor
{
public Processor() {
// Load lot of data
}
public string GetResult(string input) {
// ...
}
}
I need to implement a service wich exposes HTTP API to this class. I use Owin and Microsoft.AspNet.* libs to host HTTP Web API. For each request it creates a new thread to handle it, but I cannot instantiate Processor on every request as it takes enormous time to load some data in its constructor. Also I cannot reuse one instance from different threads as it was not designed to be thread safe. But I can instantiate several instances of Processor on service start, and then dispatch work among them. Say I allow up to 20 concurrent HTTP requests for my service. I create 20 instances of Processor and add Busy flag to the class:
class Processor
{
public bool Busy { get; set; }
// ...
}
I wrote Dispatcher class like this:
class Dispatcher
{
readonly Processor[] _processors;
readonly SemaphoreSlim _semaphore;
public Dispatcher(int maxProcessors)
{
_semaphore = new SemaphoreSlim(maxProcessors);
_processors = new Processor[maxProcessors];
// Instantiate Processors, etc...
}
public string GetResult(string input)
{
try
{
_semaphore.Wait(); // Surplus requests will wait here.
Processor processor;
lock (_processors)
{
// It is guaranteed that such processor exists if we entered the semaphore.
processor = _processors.First(p => !p.Busy);
processor.Busy = true;
}
var result = processor.GetResult(input);
processor.Busy = false;
return result;
}
finally
{
_semaphore.Release();
}
}
}
Then I can basically call it through Dispatcher in ApiController:
public class ServiceController : ApiController
{
static Dispatcher _dispatcher = new Dispatcher(20);
[Route("result")]
[HttpGet]
public string Result(string input)
{
return _dispatcher.GetResult(input);
}
}
Is it implemented correctly for my purpose?
I tested it and it works, but I wonder if I reinvented the wheel and .NET Framework has somewhat ready to use for my case, or if it could be implemented easier.
Basically in your class that is going to be run in the thread, create an event and event handler. The object that then spins up this task can register to that event. When it is raised by the task, (in this case you would raise the event when it is done) you can do something, ie. give it more work.
Create your events in the class that will be run in the child thread:
public event TaskCompleteEventHandler OnComplete;
public event TaskErrorEventHandler OnError;
Register to your events in the object that is spinning up the classes:
task.OnComplete += TaskComplete;
task.OnError += TaskComplete;
Create the function in the calling class that will handle the event:
public void TaskComplete()
{
//give the thread more work
}
Related
I need to invoke a method that meets the following criteria.
The method may run for hours.
The method may interface with hardware.
The method may request user input (parameter values, confirmation, etc). The request should block the method until input has been received.
I have a prototype implementation that fulfills this criteria using the following design.
Assume a Form exists and contains a Panel.
The IntegerInput class is a UserControl with a TextBox and a Button.
public partial class IntegerInput : UserControl
{
public TaskCompletionSource<int> InputVal = new TaskCompletionSource<int>(0);
public IntegerInput()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
int val = 0;
Int32.TryParse(textBox1.Text, out val);
InputVal.SetResult(val);
}
}
The Form1UserInput class is instanced by Form1. The container is a Panel set by Form1 before being provided to the invoking class.
public interface IUserInput
{
Task<int> GetInteger();
}
public class Form1UserInput : IUserInput
{
public Control container;
private IntegerInput integerInput = new IntegerInput();
public IntegerInput IntegerInput { get { return integerInput; } }
public async Task<int> GetInteger()
{
container.Invoke(new Action(() =>
{
container.Controls.Clear();
container.Controls.Add(integerInput);
}));
await integerInput.InputVal.Task;
return integerInput.InputVal.Task.Result;
}
}
The Demo class contains the method I want to invoke.
public class Demo
{
public IUserInput ui;
public async void MethodToInvoke()
{
// Interface with hardware...
// Block waiting on input
int val = await ui.GetInteger();
// Interface with hardware some more...
}
public async void AnotherMethodToInvoke()
{
// Interface with hardware...
// Block waiting on multiple input
int val1 = await ui.getInteger();
int val2 = await ui.getInteger();
// Interface with hardware...
}
}
This is a rough outline of what the invoking class looks like. The call to Task.Run() is accurate for my prototype.
public class Invoker
{
public async Task RunTestAsync(IUserInput ui)
{
object DemoInstance = Activator.CreateInstance(typeof(Demo));
MethodInfo method = typeof(Demo).GetMethod("MethodToInvoke");
object[] args = null;
((IUserInput)DemoInstance).ui = ui;
var t = await Task.Run(() => method.Invoke(DemoInstance, args));
// Report completion information back to Form1
}
}
The Form1 controller class instances the Invoker and calls RunTestAsync passing in an instance of Form1UserInput.
I am aware of some concerns about long running Tasks that may block and what that would mean for ThreadPool resources. However, the ability to invoke multiple methods at once is not provided by the application I am building. It's possible that the application may provide some other limited functionality while the invoked method is running but the current requirements do not specify such functionality in detail. I anticipate that there would only be one long running thread in service at any time.
Is the use of Task.Run() for this type of method invocation a reasonable implementation? If not, what would a more reasonable implementation be that provides for the required criteria? Should I consider a dedicated thread outside of the ThreadPool for this invocation?
Is the use of Task.Run() for this type of method invocation a reasonable implementation?
Assuming that your "interface with hardware" can only be done using synchronous APIs, then yes, Task.Run is fine for that.
However, I would change when it's called. Right now, Task.Run is wrapping an async void method that executes on the thread pool (and uses Invoke to jump back on the UI thread). These are each problematic: Task.Run over async void will seem to complete "early" (i.e., at the first await); and using Invoke indicates that there's some tight coupling going on (UI calls background service which calls UI).
I would replace the async void with async Task and also change where Task.Run is used to avoid Invoke:
public async Task<int> GetInteger()
{
container.Controls.Clear();
container.Controls.Add(integerInput);
// Note: not `Result`, which will wrap exceptions.
return await integerInput.InputVal.Task;
}
public async Task MethodToInvokeAsync()
{
await Task.Run(...); // Interface with hardware...
// Block waiting on input
int val = await ui.GetInteger();
await Task.Run(...); // Interface with hardware some more...
}
var t = await (Task)method.Invoke(DemoInstance, args);
Here are my project requirements:
A Windows Service that hosts a WCF service.
The WCF service must initiate and keep track of many threads.
Each thread must be identifiable by a provided key.
There will be many different types of tasks (threads), each with a "maximum running at a time" limit with the additional tasks in a queue until others of same type finish.
What I have so far:
A Windows Service that hosts a WCF service (similar to http://msdn.microsoft.com/en-us/library/ms733069(v=vs.110).aspx).
An abstract class containing a Thread (using composition because I cannot extend Thread)
Inside the WCF service class, I have a static instance of a class named MyThreadPool containing a ConcurrentDictionary that keeps record of my running threads.
My questions are:
What is the best way to remove the completed threads from the thread list (on completion of the thread)?
In this scenario, is a static instance of a ConcurrentDictionary a good method to manage threads? If not, what could be recommended?
Some of my code is shown below:
[ServiceContract(Namespace = "...")]
public interface IMyService
{
[OperationContract]
void StartProcess(int MIndexId, int MProcessId);
[OperationContract]
void StopProcess(int MIndexProcessId);
}
public class MyService : IMyService
{
private static MyThreadPool threadPool = new MyThreadPool();
public void StopProcess(int MIndexProcessId)
{
throw new NotImplementedException();
}
public void StartProcess(int ItemIdToProcess, int ProcessTypeId)
{
// call threadPool.LaunchThread(...)
}
}
public class MyThreadPool
{
private ConcurrentDictionary<int, BaseThread> _threads;
...
public void LaunchThread(BaseThread thread, int ItemIdToProcess)
{
// set additional data for thread (such as a key and name) for tracking in a database
_threads.AddOrUpdate(ItemIdToProcess, thread, (key, oldValue) => { return oldValue; });
thread.Start();
}
public void KillThread(int ItemIdToProcess)
{
...
}
}
public abstract class BaseThread
{
// some additional properties for tracking thread
// ...
private Thread _thread;
protected BaseThread()
{
_thread = new Thread(new ThreadStart(this.RunThread));
_thread.IsBackground = true;
}
// Thread methods / properties
public void Start() { _thread.Start(); }
public void Join() { _thread.Join(); }
public bool IsAlive { get { return _thread.IsAlive; } }
public string Name
{
get
{
return _thread.Name;
}
set
{
_thread.Name = value;
}
}
public void Abort()
{
_thread.Abort();
}
public abstract void RunThread();
}
public class ValidateThread : BaseThread
{
public override void RunThread()
{
...
// indicate to calling thread to remove from thread list();
}
}
Make the thread remove itself after it has done all meaningful work. Better yet, use Task with the LongRunning option. Composing tasks is easy.
Seems reasonable. You have avoided a lot of pitfalls already and the design seems solid. One pitfall with WCF services hosted in IIS is that worker processes can die at any time. You avoid that by using a Windows Service.
A Windows Service is mostly an externally started exe like any other.
One thing that is not ok, though, is: _thread.Abort(); Thread.Abort is evil. Cancellation must (not: should) be cooperative in .NET.
I have an object that takes a long time to be initialized. Therefore I the capability to Start Initializing on application startup. Any subsequent calls to methods on the class we need to have a delay mechanism that waits for the class to finish initialization.
I have a couple of potential solutions however I am not entirely satisfied with either of them. The first uses Task.Delay in a while loop and the second uses SemaphoreSlim but involves some unnecessary blocking. I feel this must be a fairly common requirement, can anybody provide some advice on how to best manage this?
Oh btw, this is a Metro application so we have limited API's
Here is the pseudocode:
public class ExposeSomeInterestingItems
{
private InitialisationState _initialised;
private readonly SemaphoreSlim _waiter =
new SemaphoreSlim(0);
public async Task StartInitialize()
{
if (_initialised == InitialisationState.Initialised)
{
throw new InvalidOperationException(
"Attempted to initialise ActiveTrackDown" +
"loads when it is already initialized");
}
_initialised =
InitialisationState.StartedInitialisation;
new TaskFactory().StartNew(async () =>
{
// This takes some time to load
this._interestingItems =
InterestingItemsLoader.LoadItems();
_waiter.Release();
_initialised = InitialisationState.Initialised;
});
}
public InterestingItem GetItem(string id)
{
DelayUntilLoaded();
DelayUntilLoadedAlternative();
}
private async Task DelayUntilLoaded()
{
if (_initialised == InitialisationState.NotInitialised)
{
throw new InvalidOperationException("Error " +
"occurred attempting to access details on " +
"ActiveTrackDownloads before calling initialise");
}
while (true)
{
if (_initialised == InitialisationState.Initialised)
{
return;
}
await Task.Delay(300);
}
}
private async Task DelayUntilLoadedAlternative()
{
if (_initialised == InitialisationState.NotInitialised)
{
throw new InvalidOperationException(
"Error occurred attempting to access details " +
"on ActiveTrackDownloads before calling initialise");
}
try
{
await _waiter.WaitAsync();
}
finally
{
_waiter.Release();
}
}
}
I think that a better design would be an asynchronous factory, where the calling code awaits the object creation and then receives a regular object instance.
Stealing liberally from Stephen Toub:
public class AsyncLazy<T> : Lazy<Task<T>>
{
public AsyncLazy(Func<T> valueFactory) :
base(() => Task.Run(valueFactory)) { }
public AsyncLazy(Func<Task<T>> taskFactory) :
base(() => Task.Run(taskFactory)) { }
public TaskAwaiter<T> GetAwaiter() { return Value.GetAwaiter(); }
}
public static class ExposeSomeInterestingItemsFactory
{
public static AsyncLazy<ExposeSomeInterestingItems> Instance
{
get { return _instance; }
}
private static readonly AsyncLazy<ExposeSomeInterestingItems> _instance =
new AsyncLazy<ExposeSomeInterestingItems>(() => new ExposeSomeInterestingItems());
public static void StartInitialization()
{
var unused = Instance.Value;
}
}
public class ExposeSomeInterestingItems
{
public ExposeSomeInterestingItems()
{
// This takes some time to load
this._interestingItems = InterestingItemsLoader.LoadItems();
}
public InterestingItem GetItem(string id)
{
// Regular logic. No "delays".
}
}
...
var exposeSomeInterestingItems = await ExposeSomeInterestingItemsFactory.Instance;
var item = exposeSomeInterestingItems.GetItem("id");
That way, you keep the Single Responsibility Principle nicely:
AsyncLazy<T> combines Task<T> with Lazy<T> (so the instance is created asynchronously only when needed).
ExposeSomeInterestingItemsFactory contains construction logic.
ExposeSomeInterestingItems is only concerned with exposing interesting items, rather than having to pollute all its members with asynchronous delays.
Also, this solution is asynchronous throughout (no blocking), which is good (particularly for Metro apps).
Update, 2012-09-14: I've taken this code and cleaned it up and commented it on my blog.
You can use the Task<T> for this. This will take care of all the synchronisation for you and allows you to block untill the value is available:
private static Task<HeavyObject> heavyObjectInitializer;
// Call this method during application initialization
public static void Bootstrap()
{
heavyObjectInitializer = new Task<HeavyObject>(() =>
{
// creation of heavy object here
return new HeavyObject();
});
// Start running the initialization right now on a
// background thread. We don't have to wait on this.
heavyObjectInitializer.Start();
}
// Call this method whenever you need to use the object.
public static HeavyObject GetHeavyObject()
{
// Get the initialized object, or block untill this
// instance gets available.
return heavyObjectInitializer.Result;
}
Optionally, you can also query to see if the object is available or not:
public static bool IsHeavyObjectAvailable
{
get { return heavyObjectInitializer.IsCompleted; }
}
Put the method calls into a queue which you process when you finish initialising. Only put methods into the queue when you have not yet initialised.
You could move to a an event driven architecture where you application is in different states.
Initially the application moves into the Starting state. In this state HeavyObject is created using a background task. When the initialization is complete an event is fired. (You don't have to use an actual .NET event. You can use callbacks or something similar and frameworks like Reactive Extensions allows you to compose sequences of events.)
When all initialization events have fired you move into the Started state of your application. For an UI application this could modify the UI to enable some previously disabled operations.
Check this Prototype Pattern. Maybe it can help you
You only need to create your object once and clone it when you need another one.
I'd like to hear opinions on the best way to handle asynchronous operations with the Command pattern. Say we have the following example:
public class MyCommand
{
// Sets up receiver and does whatever stuff
public void Execute()
{
_myReceiver.DoSomething();
}
}
The problem is: MyCommand doesn't know whether MyReceiver.DoSomething() has async portions of code. If i wanted to push MyCommand into an undo stack after its execution, i couldn't guarantee that its receiver action has been fully executed, making it uncertain to know if MyCommand reached a state where undoing is possible or not.
I personally thought on the following solution:
Implement some sort of state control in Command
Include "BeginExecute" and "EndExecute" in Command
Include events in MyReceiver and make Command subscribe to them (that seems smelly to me)
To wrap things up, MyCommand would turn into:
public class MyCommand
{
public MyCommand(MyReceiver receiver)
{
_myReceiver = receiver;
_myReceiver.DoSomethingFinished += () => this.EndExecute();
}
public void BeginExecute()
{
this.EnterExecutionState();
_myReceiver.DoSomething();
}
public void EndExecute()
{
this.LeaveExecutionState();
}
// State handling related stuff
}
I now have the means to make sure the Command's receiver has finished executing whatever action and it's ready to be pushed into the undo stack. However, to event-spam every single Receiver class that contains async operations really bugs me.
I haven't found much about this topic in the Internet and would love to hear different approaches.
OBS: Make the Command manage all the asynchronous-related code isn't an option :).
I think you've got way too much going on in a single class. I would break it down like this:
// An immutable command, to be handled in-process.
// ICommand is a marker interface with no members.
public class DoSomething : ICommand
{
public readonly Id;
public DoSomething(Guid id)
{
Id = id;
}
}
// To be handled out-of-process.
[AsynchronousCommand]
public class DoSomethingThatTakesAReallyLongTime : ICommand
{
public readonly Id;
public DoSomethingThatTakesAReallyLongTime(Guid id)
{
Id = id;
}
}
// This guy could take any number of dependencies: ISomethingRepository, DbContext, etc.
// Doesn't matter, but it's probably gonna have dependencies.
public class DoSomethingHandler : IHandler<DoSomething>
{
public void Handle(DoSomething command) // IHandler<T>'s only member
{
// CRUD or call call a domain method
}
}
public class CommandService : ICommandService
{
public void Execute(params ICommand[] commands) // ICommandService's only member
{
foreach(var command in commands)
{
var handler = GetHandler(command); // Could use your IOC container.
if (HasAsyncAttribute())
new Action(() => handler.Handle(command)).BeginInvoke(null, null);
else
handler.Handle(command);
}
}
}
// Something that might consume these
public class SomethingController
{
private readonly ICommandService _commandService;
public SomethingController(ICommandService commandService)
{
_commandService = commandService;
}
[HttpPost]
public void DoSomething(Guid id)
{
_commandService.Execute(new DoSomething(id));
}
[HttpPost]
public void DoSomethingThatTakesAReallyLongTime(Guid id)
{
_commandService.Execute(new DoSomethingThatTakesAReallyLongTime(id));
}
}
The big advantage here is that you can distribute your commands to clients without explicitly dragging along all the dependencies that go with the handlers. The handlers should not be known to the client. All the client needs to know is that it sent a command, and all commands should be assumed to succeed.
Something like this?
public interface ICommand
{
void Execute();
event EventHandler Finished;
}
public class MyCommand : ICommand
{
public MyCommand(MyReceiver receiver)
{
_myReceiver = receiver;
_myReceiver.DoSomethingFinished += () => Finished(); // dont forget null check here.
}
public void Execute()
{
_myReceiver.DoSomething();
}
public event EventHandler Finished;
}
This way, user of this command can register to Finished event so it knows when command has finished its async behaviour and can act acordingly.
Or if you dont wan't to use event, then what about callback?
public class MyCommand : ICommand
{
public MyCommand(MyReceiver receiver)
{
_myReceiver = receiver;
}
public void Execute()
{
_myReceiver.DoSomething(() => Finished()); // dont forget null check here.
}
public event EventHandler Finished;
}
Either way, there simply need to be a way for MyReciever to notify its caller, that it finished. There is no way to bypass it.
First I would add to the name of the method Async to esplicitly signal to your Command class consumer that method executes in async way.
Second, I would add like parameter an Action<T> which will be called as method async call completes. So this method caller can be notified when async sction was terminated.
Edit
obj.DoSomethingAsync(... params, Action<T> onComplete)
If you are going to impose the requirement that all processing is completed before control returns to your Execute method, without modifying the calling code's behavior, you could modify the way that your actions execute.
First initialize all your asynchronous calls and block(wait) on the current thread for calls to return. I'm not sure what the nature of your asynchronous calls are, as in if they are in a Thread that you are aware of, or will be returned on an arbitrary thread, but you should be able to come up with some kind of thread synchronization for your problem.
Try using a Semaphore to block current thread(after calling your async methods), and release the semaphore when all your async methods have returned their response(s). This will have the effect of "re-synchronizing" your async calls.
You can use another synchronization method, but a Semaphore is simple enough to understand.
I have a class that basically stores files in amazon s3.
Here is what it looks like (simplified)
public class S3FileStore
{
public void PutFile(string ID, Stream content)
{
//do stuff
}
}
In my client app, I want to be able to call:
var s3 = new() S3FileStore();
s3.PutFile ("myId", File.OpenRead(#"C:\myFile1"));
s3.PutFile ("myId", File.OpenRead(#"C:\myFile2"));
s3.PutFile ("myId", File.OpenRead(#"C:\myFile3"));
I want this to be an asynchronous operation - I want the S3FileStore to handle this (i don't want my caller to have to execute PutFile asynchronously so to speak) but, i want to be able to trap exceptions / tell if the operation completed for each file.
I've looked at event based async calls, especially this:
http://blogs.windowsclient.net/rendle/archive/2008/11/04/functional-shortcuts-2-event-based-asynchronous-pattern.aspx
However, I can't see how to call my PutFile (void) method?
Are there any better examples?
Look at the solution for this question: Adding cancel ability and exception handling to async code . Hope it helps.
The BackgroundWorker base class might be worth a look, and also the Thread Pool:
ThreadPool.QueueUserWorkItem(delegate
{
s3.PutFile ("myId", File.OpenRead(#"C:\myFile1"));
});
This is basically what you would do with the Action/BeginInvoke pattern. With BeginInvoke, you additionally receive an IAsyncResult on which you can call .WaitOne() to block the current thread until the operation finished, in case you need that. You would trigger a new BeginInvoke for every file you'd like to save.
If you need to do this frequently, a more sophisticated version could be to use a Queue in combination with the BackgroundWorker, e.g.:
public sealed class S3StoreLikePutFileWorker<TYourData> : BackgroundWorker
{
private AutoResetEvent WakeUpEvent = new AutoResetEvent(false);
private Queue<TYourData> DataQueue = new Queue<TYourData>();
private volatile bool StopWork = false;
public void PutFile(TYourData dataToWrite)
{
DataQueue.Enqueue(dataToWrite);
WakeUpEvent.Set();
}
public void Close()
{
StopWork = true;
WakeUpEvent.Set();
}
private override void OnDoWork(DoWorkEventArgs e)
{
do
{
// sleep until there is something to do
WakeUpEvent.WaitOne();
if(StopWork) break;
// Write data, if available
while(DataQueue.Count > 0)
{
TYourData yourDataToWrite = DataQueue.Dequeue();
// write data to file
}
}
while(!StopWork);
}
}
Depending on how much complexity you need.
The BackgroundWorker supports progress feedback (set WorkerReportsProgress = true; in the constructor), and you can also add a custom event to report errors, if that is necessary:
// create a custom EventArgs class that provides the information you need
public sealed class MyEventArgs : EventArgs {
// Add information about the file
}
// ... define the event in the worker class ...
public event EventHandler<MyEventArgs> ErrorOccured;
// ... call it in the worker class (if needed) ...
if(ErrorOccured != null) ErrorOccured(this, new MyEventArgs(/*...*/));