Reputation: 3314
I have code with Parallel.Foreach which is processing files and doing some operation on each file in parallel.
Parallel.ForEach(lstFiles, file=>
{
// Doing some operation on file
// Skip file and move to next if it is taking too long
});
I want to skip a file and move to next file (but don't want to exit the Parallel.Foreach) if a particular file is taking too long (say 2 mins). Is there any way in Parallel.Foreach to check the time taken by thread to process a single file.
Thanks
Upvotes: 0
Views: 325
Reputation: 117124
I'd suggest you don't use Parallel.ForEach
and instead use Mirosoft's extremely more powerful Reactive Framework. Then you can do this:
var query =
from file in lstFiles.ToObservable()
from result in Observable.Amb(
Observable.Start(() => SomeOperation(file)).Select(_ => true),
Observable.Timer(TimeSpan.FromMinutes(2.0)).Select(_ => false))
select new { file, result };
IDisposable subscription =
query
.Subscribe(x =>
{
/* do something with each `new { file, result }`
as they arrive. */
}, ex =>
{
/* do something if an error is encountered */
/* (stops processing on first error) */
}, () =>
{
/* do something if they have all finished successfully */
})
This is all done in parallel. The Observable.Amb
operator starts the two observables defined in its argument list and takes the value from which ever of the two produces a value first - if it's the Start
observable it has processed your file and if it's the Timer
observable then 2.0
minutes has elapsed without a result from the file.
If you want to stop the processing when it is half-way through then just call subscription.Dispose()
.
Use NuGet "System.Reactive" to get the bits.
The query in lambda form as per request in comments:
var query =
lstFiles
.ToObservable()
.SelectMany(
file =>
Observable.Amb(
Observable.Start(() => SomeOperation(file)).Select(_ => true),
Observable.Timer(TimeSpan.FromMinutes(2.0)).Select(_ => false)),
(file, result) => new { file, result });
Upvotes: 1