Skip to content
This repository was archived by the owner on Dec 5, 2024. It is now read-only.

Commit a70befd

Browse files
committed
Wrapped tasks raise events in the correct order, also handle exceptions properly
1 parent c826a16 commit a70befd

File tree

4 files changed

+72
-14
lines changed

4 files changed

+72
-14
lines changed

src/GitHub.Api/NewTaskSystem/ActionTask.cs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ class ActionTask : TaskBase
1010
protected Action<bool> Callback { get; }
1111
protected Action<bool, Exception> CallbackWithException { get; }
1212

13+
public ActionTask(CancellationToken token, Action action)
14+
: base(token)
15+
{
16+
Guard.ArgumentNotNull(action, "action");
17+
this.Callback = _ => action();
18+
Name = "ActionTask";
19+
}
20+
1321
public ActionTask(CancellationToken token, Action<bool> action)
1422
: base(token)
1523
{
@@ -123,6 +131,14 @@ class FuncTask<T> : TaskBase<T>
123131
protected Func<bool, T> Callback { get; }
124132
protected Func<bool, Exception, T> CallbackWithException { get; }
125133

134+
public FuncTask(CancellationToken token, Func<T> action)
135+
: base(token)
136+
{
137+
Guard.ArgumentNotNull(action, "action");
138+
this.Callback = _ => action();
139+
Name = $"FuncTask<{typeof(T)}>";
140+
}
141+
126142
public FuncTask(CancellationToken token, Func<bool, T> action)
127143
: base(token)
128144
{

src/GitHub.Api/NewTaskSystem/TaskBase.cs

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,30 @@ public TaskBase(CancellationToken token)
8080

8181
public TaskBase(Task task)
8282
{
83-
task.ContinueWith(t =>
83+
Task = new Task(t =>
8484
{
85+
var scheduler = TaskManager.GetScheduler(Affinity);
8586
RaiseOnStart();
86-
RaiseOnEnd();
87-
}, Token, runAlwaysOptions, TaskScheduler.Current);
88-
Task = task;
87+
var tk = ((Task)t);
88+
try
89+
{
90+
if (tk.Status == TaskStatus.Created && !tk.IsCompleted &&
91+
((tk.CreationOptions & (TaskCreationOptions)512) == TaskCreationOptions.None))
92+
{
93+
tk.RunSynchronously(scheduler);
94+
}
95+
}
96+
catch (Exception ex)
97+
{
98+
Errors = ex.Message;
99+
if (!RaiseFaultHandlers(ex))
100+
throw;
101+
}
102+
finally
103+
{
104+
RaiseOnEnd();
105+
}
106+
}, task, Token, TaskCreationOptions.None);
89107
}
90108

91109
protected TaskBase() {}
@@ -395,7 +413,33 @@ public TaskBase(CancellationToken token)
395413
public TaskBase(Task<TResult> task)
396414
: base()
397415
{
398-
Task = task;
416+
var scheduler = TaskManager.GetScheduler(Affinity);
417+
Task = new Task<TResult>(t =>
418+
{
419+
TResult ret = default(TResult);
420+
RaiseOnStart();
421+
var tk = ((Task<TResult>)t);
422+
try
423+
{
424+
if (tk.Status == TaskStatus.Created && !tk.IsCompleted &&
425+
((tk.CreationOptions & (TaskCreationOptions)512) == TaskCreationOptions.None))
426+
{
427+
tk.RunSynchronously();
428+
}
429+
ret = tk.Result;
430+
}
431+
catch (Exception ex)
432+
{
433+
Errors = ex.Message;
434+
if (!RaiseFaultHandlers(ex))
435+
throw;
436+
}
437+
finally
438+
{
439+
RaiseOnEnd();
440+
}
441+
return ret;
442+
}, task, Token, TaskCreationOptions.None);
399443
}
400444

401445

src/tests/TaskSystemIntegrationTests/Tests.cs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -656,15 +656,11 @@ class TaskToActionTask : BaseTest
656656
[Test]
657657
public async Task CanWrapATask()
658658
{
659-
var uiThread = 0;
660-
await new ActionTask(Token, _ => uiThread = Thread.CurrentThread.ManagedThreadId) { Affinity = TaskAffinity.UI }
661-
.StartAsAsync();
662-
663659
var runOrder = new List<string>();
664-
var task = new Task(() => runOrder.Add($"ran {Thread.CurrentThread.ManagedThreadId}"));
665-
var act = new ActionTask(task) { Affinity = TaskAffinity.UI };
660+
var task = new Task(() => runOrder.Add($"ran"));
661+
var act = new ActionTask(task) { Affinity = TaskAffinity.Exclusive };
666662
await act.Start().Task;
667-
CollectionAssert.AreEqual(new string[] { $"ran {uiThread}" }, runOrder);
663+
CollectionAssert.AreEqual(new string[] { $"ran" }, runOrder);
668664
}
669665

670666
/// <summary>
@@ -820,9 +816,10 @@ public TaskBase Test_GetTopMostTaskInCreatedState()
820816
}
821817

822818
[Test]
823-
public void GetTopMostTaskInCreatedState()
819+
public async Task GetTopMostTaskInCreatedState()
824820
{
825-
var task1 = new ActionTask(TaskEx.FromResult(true));
821+
var task1 = new ActionTask(Token, () => { });
822+
await task1.StartAwait();
826823
var task2 = new TestActionTask(Token, _ => { });
827824
var task3 = new TestActionTask(Token, _ => { });
828825

src/tests/TaskSystemIntegrationTests/ThreadSynchronizationContext.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ private void Wait(long id)
4949

5050
private void Start()
5151
{
52+
SetSynchronizationContext(this);
5253
threadId = Thread.CurrentThread.ManagedThreadId;
5354
var lastTime = DateTime.Now.Ticks;
5455
var wait = new ManualResetEventSlim(false);

0 commit comments

Comments
 (0)