Cancelling Parallel.For with CancellationToken using method - c#

I need to Cancel all Tasks made by Parallel.For when using function.
For example:
class Example
{
private CancellationTokenSource cts;
public Example()
{
cts = new CancellationTokenSource();
}
public void plsCompute()
{
ParallelOptions po = new ParallelOptions{ CancellationToken = cts.Token };
Parallel.For(0, 10, po, (i) => compute());
}
public void plsStopComputing()
{
cts.Cancel();
}
public void compute()
{
for(int i=0;i<100000;i++){
if(//token was cancelled){
Console.WriteLine("Cancelled");
return;
}
//do something
}
}
I need to stop all task that are currently runing, not creating new tasks.
Is there any way to achieve this?
All examples I've seen was with function made in lambda, so there I could access cts. I need it to be in other funtion. Also if I passed token as a parameter it didnt work. cts token was changed but in other threads it didnt change.
Any help appriciated :)
EDIT
As I mentioned in comment, I got deeper, this example is not really what I want. These methods are invoked by messeges sent through msmq from an wpf app. I think that every time I call from wpf, service makes new instance of this class, so it cancels new instance instead of the one that is already computing.
Is there a way to call the same instance?

The problem was with invoking by msmq, that every time message was received it created new instance of class.
I've solved it adding
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
Above declaration of class that implements service

Related

Should/Could this "recursive Task" be expressed as a TaskContinuation?

In my application I have the need to continually process some piece(s) of Work on some set interval(s). I had originally written a Task to continually check a given Task.Delay to see if it was completed, if so the Work would be processed that corresponded to that Task.Delay. The draw back to this method is the Task that checks these Task.Delays would be in a psuedo-infinite loop when no Task.Delay is completed.
To solve this problem I found that I could create a "recursive Task" (I am not sure what the jargon for this would be) that processes the work at the given interval as needed.
// New Recurring Work can be added by simply creating
// the Task below and adding an entry into this Dictionary.
// Recurring Work can be removed/stopped by looking
// it up in this Dictionary and calling its CTS.Cancel method.
private readonly object _LockRecurWork = new object();
private Dictionary<Work, Tuple<Task, CancellationTokenSource> RecurringWork { get; set; }
...
private Task CreateRecurringWorkTask(Work workToDo, CancellationTokenSource taskTokenSource)
{
return Task.Run(async () =>
{
// Do the Work, then wait the prescribed amount of time before doing it again
DoWork(workToDo);
await Task.Delay(workToDo.RecurRate, taskTokenSource.Token);
// If this Work's CancellationTokenSource is not
// cancelled then "schedule" the next Work execution
if (!taskTokenSource.IsCancellationRequested)
{
lock(_LockRecurWork)
{
RecurringWork[workToDo] = new Tuple<Task, CancellationTokenSource>
(CreateRecurringWorkTask(workToDo, taskTokenSource), taskTokenSource);
}
}
}, taskTokenSource.Token);
}
Should/Could this be represented with a chain of Task.ContinueWith? Would there be any benefit to such an implementation? Is there anything majorly wrong with the current implementation?
Yes!
Calling ContinueWith tells the Task to call your code as soon as it finishes. This is far faster than manually polling it.

Limit number of parallel running methods

In my class I have a download function. Now in order to not allow a too high number of concurrent downloads, I would like to block this function until a "download-spot" is free ;)
void Download(Uri uri)
{
currentDownloads++;
if (currentDownloads > MAX_DOWNLOADS)
{
//wait here
}
DoActualDownload(uri); // blocks long time
currentDownloads--;
}
Is there a ready made programming pattern for this in C# / .NET?
edit: unfortunatelyt i cant use features from .net4.5 but only .net4.0
May be this
var parallelOptions = new ParallelOptions
{
MaxDegreeOfParallelism = 3
};
Parallel.ForEach(downloadUri, parallelOptions, (uri, state, index) =>
{
YourDownLoad(uri);
});
You should use Semaphore for this concurrency problem, see more in the documentation:
https://msdn.microsoft.com/en-us/library/system.threading.semaphore(v=vs.110).aspx
For such cases, I create an own Queue<MyQuery> in a custom class like QueryManager, with some methods :
Each new query is enqueued in Queue<MyQuery> queries
After each "enqueue" AND in each query answer, I call checkIfQueryCouldBeSent()
The checkIfQueryCouldBeSent() method checks your conditions : number of concomitant queries, and so on. In your case you accept to launch a new query if global counter is less than 5. And you increment the counter
Decrement the counter in query answer
It works only if all your queries are asynchronous.
You have to store Callback in MyQuery class, and call it when query is over.
You're doing async IO bound work, there's no need to be using multiple threads with a call such as Parallel.ForEach.
You can simply use naturally async API's exposed in the BCL, such ones that make HTTP calls using HttpClient. Then, you can throttle your connections using SemaphoreSlim and it's WaitAsync method which asynchronously waits:
private readonly SemaphoreSlim semaphoreSlim = new SemaphoreSlim(3);
public async Task DownloadAsync(Uri uri)
{
await semaphoreSlim.WaitAsync();
try
{
string result = await DoActualDownloadAsync(uri);
}
finally
{
semaphoreSlim.Release();
}
}
And your DoActualyDownloadAsync will use HttpClient to do it's work. Something along the lines of:
public Task<string> DoActualDownloadAsync(Uri uri)
{
var httpClient = new HttpClient();
return httpClient.GetStringAsync(uri);
}

Non blocking and reoccurring producer/consumer notifier implementation

Searched hard for a piece of code which does what i want and i am happy with. Reading this and this helped a lot.
I have a scenario where i need a single consumer to be notified by a single producer when new data is available but would also like the consumer to be notified periodically regardless of if new data is available.
It is fine if the consumer is notified more than the reoccurring period but it should not be notified less frequent.
It is possible that multiple notifications for 'new data' occur while the consumer is already notified and working. (So SemaphoreSlim was not a good fit).
Hence, a consumer which is slower than the rate of producer notifications, would not queue up subsequent notifications, they would just "re-signal" that same "data available" flag without affect.
I would also like the consumer to asynchronously wait for the notifications (without blocking a thread).
I have stitched together the below class which wraps around TaskCompletionSource and also uses an internal Timer.
public class PeriodicalNotifier : IDisposable
{
// Need some dummy type since TaskCompletionSource has only the generic version
internal struct VoidTypeStruct { }
// Always reuse this allocation
private static VoidTypeStruct dummyStruct;
private TaskCompletionSource<VoidTypeStruct> internalCompletionSource;
private Timer reSendTimer;
public PeriodicalNotifier(int autoNotifyIntervalMs)
{
internalCompletionSource = new TaskCompletionSource<VoidTypeStruct>();
reSendTimer = new Timer(_ => Notify(), null, 0, autoNotifyIntervalMs);
}
public async Task WaitForNotifictionAsync(CancellationToken cancellationToken)
{
using (cancellationToken.Register(() => internalCompletionSource.TrySetCanceled()))
{
await internalCompletionSource.Task;
// Recreate - to be able to set again upon the next wait
internalCompletionSource = new TaskCompletionSource<VoidTypeStruct>();
}
}
public void Notify()
{
internalCompletionSource.TrySetResult(dummyStruct);
}
public void Dispose()
{
reSendTimer.Dispose();
internalCompletionSource.TrySetCanceled();
}
}
Users of this class can do something like this:
private PeriodicalNotifier notifier = new PeriodicalNotifier(100);
// ... In some task - which should be non-blocking
while (some condition)
{
await notifier.WaitForNotifictionAsync(_tokenSource.Token);
// Do some work...
}
// ... In some thread, producer added new data
notifier.Notify();
Efficiency is important to me, the scenario is of a high frequency data stream, and so i had in mind:
The non-blocking nature of the wait.
I assume Timer is more efficient than recreating Task.Delay and cancelling it if it's not the one to notify.
A concern for the recreation of the TaskCompletionSource
My questions are:
Does my code correctly solve the problem? Any hidden pitfalls?
Am i missing some trivial solution / existing block for this use case?
Update:
I have reached a conclusion that aside from re implementing a more lean Task Completion structure (like in here and here) i have no more optimizations to make. Hope that helps anyone looking at a similar scenario.
Yes, your implementation makes sense but the TaskCompletionSource recreation should be outside the using scope, otherwise the "old" cancellation token may cancel the "new" TaskCompletionSource.
I think using some kind of AsyncManualResetEvent combined with a Timer would be simpler and less error-prone. There's a very nice namespace with async tools in the Visual Studio SDK by Microsoft. You need to install the SDK and then reference the Microsoft.VisualStudio.Threading assembly. Here's an implementation using their AsyncManualResetEvent with the same API:
public class PeriodicalNotifier : IDisposable
{
private readonly Timer _timer;
private readonly AsyncManualResetEvent _asyncManualResetEvent;
public PeriodicalNotifier(TimeSpan autoNotifyInterval)
{
_asyncManualResetEvent = new AsyncManualResetEvent();
_timer = new Timer(_ => Notify(), null, TimeSpan.Zero, autoNotifyInterval);
}
public async Task WaitForNotifictionAsync(CancellationToken cancellationToken)
{
await _asyncManualResetEvent.WaitAsync().WithCancellation(cancellationToken);
_asyncManualResetEvent.Reset();
}
public void Notify()
{
_asyncManualResetEvent.Set();
}
public void Dispose()
{
_timer.Dispose();
}
}
You notify by setting the reset event, asynchronously wait using WaitAsync, enable Cancellation using the WithCancellation extension method and then reset the event. Multiple notifications are "merged" by setting the same reset event.
Subject<Result> notifier = new Subject<Result)();
notifier
.Select(value => Observable.Interval(TimeSpan.FromMilliSeconds(100))
.Select(_ => value)).Switch()
.Subscribe(value => DoSomething(value));
//Some other thread...
notifier.OnNext(...);
This Rx query will keep sending value, every 100 milliseconds, until a new value turns up. Then we notify that value every 100 milliseconds.
If we receive values faster than once every 100 milliseconds, then we basically have the same output as input.

Proxy or FiddlerCore

I'm trying to write a program that catches the HTTP get requests.
I have found Fiddler-core a genius library that should do exactly what I want.
The thing is, I'm trying to execute a big piece code-work inside the void FiddlerApplication_BeforeRequest(Session oSession) and it seems to block all the request and damage my surfing speed a great deal.
I have tried to use threads/tasks with no avail.
What am I doing wrong?
This is my code:
public event RequestCapture RequestCaptured;
private CancellationTokenSource cancelTokenSource = new CancellationTokenSource();
//...stat public function:
public void RunWatch() {
Fiddler.FiddlerApplication.BeforeRequest += FiddlerApplication_BeforeRequest;
Fiddler.FiddlerApplication.Startup(0, FiddlerCoreStartupFlags.Default);
}
void FiddlerApplication_BeforeRequest(Session oSession)
{
if (RequestCaptured != null)
{
CancellationToken ct = cancelTokenSource.Token;
Task.Factory.StartNew(() =>RequestCaptured(oSession.fullUrl), ct);
//Handle the event in a new thread, so the Listener will continue to listen
}
}
//close public function:
public void Close() {
try
{
FiddlerApplication.Shutdown();
cancelTokenSource.Cancel();
}
catch { }
}
now i have i different class that do that:
public Form1()
{
Listiner = new HttpWatcher.Listner();
Listiner.RequestCaptured += RequestCaptured;
Listiner.RunWatch();
}
void RequestCaptured(string url)
{
System.Threading.Thread.Sleep(10000);
}
edit
The question is: Is there a better way using fiddler-core? or am i to build a simple proxy for that? using something else? Thanks!
edit2
I have edited the code, so it would fill the missing parts.
Just to be clear here, FiddlerCore processes each Session on a threadpool thread. If you need blocking behavior, there's no need to spin up an additional thread or anything like that. If you don't need to process things in a blocking manner, then feel free to queue the data on a background queue and use tasks or another asynchronous mechanism to perform processing.
You should explain exactly what you mean when you say damage my surfing speed a great deal, and whether or not you see different behavior when using Fiddler rather than your application.

How can I get my application to continue, only when all async operations are complete?

In my application, I used to create along string of async operations, which passed in functions like this:
public void LotsOfAsync()
{
DoAsync1( ()=> { DoAsync2( ()=> { doAsync3( ()=> { finalAction();}) } ) } );
}
However, now I have moved many of those async operations into separate classes and objects but I want the same results. Mainly I have moved those async operations into classes which become part of a collection.
I'd like my new code to look like this:
public void lotsOfAsync()
{
DoAsync1();
for each ( MyClass in Async1List)
{
MyClass.DoAsyn2();
}
if (allAsyncOperationsAreComplete)
{
FinalAction();
}
}
What things do I need to do, to get this to work? Thanks.
Using the Answer below about Tasks, something still seems to be lacking. The program never continues even after throwing everything into a BackgroundWorker.
You can use Task<T> (using the Task Parallel Library for Silverlight) - something like this maybe:
List<Task> tasks = new List<Task>();
Task.Factory.StartNew(() => DoAsync1()).ContinueWith(_ =>
{
foreach (MyClass myClass in Async1List)
{
tasks.Add(Task.Factory.StartNew(() => myClass.DoSomething()));
}
Task.WaitAll(tasks.ToArray());
FinalAction();
});
Im not familiar with wp7, but you may use counter as static field and check if it's equal to 0 in final action.
Every MyClass.DoAsyn2() should fire maybe a event, or any other code to signal that it is finished.
Another option is to move all async to task and call Task.WaitAll
http://msdn.microsoft.com/en-us/library/dd270695.aspx
Have you had a look at the CountdownEvent in .Net 4? This is a signalling construct where one thread will block and only proceed once other threads have completed and called set on the count down event. You initialise it with the number of signals you need before the thread calling Wait on the construct will proceed. E.g.:
CountdownEvent countdown = new CountdownEvent(3);
will only let the thread calling Wait to proceed once 3 other threads have called Signal.
So your example would perhaps look something like this:
public void lotsOfAsync()
{
Int32 numberOfAsyncProcesses = Async1List.Length + 1;
CountdownEvent countdown = new CountdownEvent (numberOfAsyncProcesses);
DoAsync1(countdown); // call countdown.signal() in the async method once complete.
for each ( MyClass in Async1List)
{
// call countdown.signal() in the async method once complete.
MyClass.DoAsyn2(countdown);
}
if(countDown.Wait(TimeSpan.FromSeconds(3))
{
FinalAction();
}
}
I've also added a timeout where the calling thread will unblock after 3 seconds if failed to get a response from all processing threads. In this case, the final action will not be performed.
You can reproduce this with Monitor/Pulse if you are not targeting .Net 4.
There is a nice example here too. Hope this helps!
After looking through all the previous answers, I was unable to solve my problem.
Instead what I needed to do, was create custom Events within my classes, which triggered upon a successful completion of the asynchronous tasks.
The website that proved the most useful to me to accomplish this was: http://www.marten-online.com/csharp/simple-custom-event-handling.html
My final code looked something like this:
public void lotsOfAsync()
{
DoAsync1();
for each ( MyClass in Async1List)
{
MyClass.PropertyChange += new MyClass.PropertyChangeHandler(Async2Complete);
MyClass.DoAsyn2();
}
}
public void Async2Complete(object sender, PropertyChangeEventArgs data)
{
if (data.PropertyName == "AsyncComplete")
{
totalAsyncCompleted++;
if (totalAsyncCompleted >= Async1List.Count)
{
FinalAction();
}
}
}
Have you heard of the Deferred pattern often used in Javascript?
It is simple to work with and very dynamic and you should be able to implement it on Windows phone aswell.
Have a look at this guide
http://twistedmatrix.com/documents/current/core/howto/defer.html
Regards
Tobias

Categories

Resources