forked from kevinkinnett/BitSharp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathOnCompleteBlock.cs
53 lines (48 loc) · 2.01 KB
/
OnCompleteBlock.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;
namespace BitSharp.Common
{
public static class OnCompleteBlock
{
/// <summary>
/// Create a block which passes through items from a source block, and calls an action before completing.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="source"></param>
/// <param name="onCompleteAction"></param>
/// <param name="cancelToken"></param>
/// <returns></returns>
public static ISourceBlock<T> Create<T>(ISourceBlock<T> source, Action onCompleteAction, CancellationToken cancelToken = default(CancellationToken))
{
if (source == null)
throw new ArgumentNullException(nameof(source));
if (onCompleteAction == null)
throw new ArgumentNullException(nameof(onCompleteAction));
var passthrough = new TransformBlock<T, T>(item => item);
source.LinkTo(passthrough, new DataflowLinkOptions { PropagateCompletion = false });
source.Completion.ContinueWith(
task =>
{
var passthroughBlock = (IDataflowBlock)passthrough;
try
{
if (task.Status == TaskStatus.RanToCompletion)
onCompleteAction();
if (task.IsCanceled)
passthroughBlock.Fault(new OperationCanceledException());
else if (task.IsFaulted)
passthroughBlock.Fault(task.Exception);
else
passthrough.Complete();
}
catch (Exception ex)
{
passthroughBlock.Fault(ex);
}
}, cancelToken);
return passthrough;
}
}
}