Skip to content

Commit 5fbd2db

Browse files
author
Darran
committed
Verify can deadlock in certain situations, because of the use of a local function.
#99 opened on May 29 by DalSoft Verify should take an action as well as a Func #96 opened on Mar 19 by DalSoft
1 parent 5e96749 commit 5fbd2db

3 files changed

Lines changed: 58 additions & 10 deletions

File tree

DalSoft.RestClient.sln

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DalSoft.RestClient.Test.Uni
1111
EndProject
1212
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DalSoft.RestClient.Examples", "DalSoft.RestClient.Examples\DalSoft.RestClient.Examples.csproj", "{41991191-F064-44CB-A8E8-27ED78A90707}"
1313
EndProject
14+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DalSoft.RestClient.Benchmark", "DalSoft.RestClient.Benchmark\DalSoft.RestClient.Benchmark.csproj", "{B69A4A5A-F3BE-4CE5-9047-5F9543EC8490}"
15+
EndProject
16+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DalSoft.RestClient.Benchmark.WebApi", "DalSoft.RestClient.Benchmark.WebApi\DalSoft.RestClient.Benchmark.WebApi.csproj", "{CC8A0956-8386-4F29-BEC3-B79A5394F37F}"
17+
EndProject
1418
Global
1519
GlobalSection(SolutionConfigurationPlatforms) = preSolution
1620
Debug|Any CPU = Debug|Any CPU
@@ -33,6 +37,14 @@ Global
3337
{41991191-F064-44CB-A8E8-27ED78A90707}.Debug|Any CPU.Build.0 = Debug|Any CPU
3438
{41991191-F064-44CB-A8E8-27ED78A90707}.Release|Any CPU.ActiveCfg = Release|Any CPU
3539
{41991191-F064-44CB-A8E8-27ED78A90707}.Release|Any CPU.Build.0 = Release|Any CPU
40+
{B69A4A5A-F3BE-4CE5-9047-5F9543EC8490}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
41+
{B69A4A5A-F3BE-4CE5-9047-5F9543EC8490}.Debug|Any CPU.Build.0 = Debug|Any CPU
42+
{B69A4A5A-F3BE-4CE5-9047-5F9543EC8490}.Release|Any CPU.ActiveCfg = Release|Any CPU
43+
{B69A4A5A-F3BE-4CE5-9047-5F9543EC8490}.Release|Any CPU.Build.0 = Release|Any CPU
44+
{CC8A0956-8386-4F29-BEC3-B79A5394F37F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
45+
{CC8A0956-8386-4F29-BEC3-B79A5394F37F}.Debug|Any CPU.Build.0 = Debug|Any CPU
46+
{CC8A0956-8386-4F29-BEC3-B79A5394F37F}.Release|Any CPU.ActiveCfg = Release|Any CPU
47+
{CC8A0956-8386-4F29-BEC3-B79A5394F37F}.Release|Any CPU.Build.0 = Release|Any CPU
3648
EndGlobalSection
3749
GlobalSection(SolutionProperties) = preSolution
3850
HideSolutionNode = FALSE

DalSoft.RestClient/DalSoft.RestClient.csproj

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,17 @@
66
Chain methods to create the uri and verb for example new RestClient("https://jsonplaceholder.typicode.com").Posts(1).Get()
77
Explicit and implicit casting from dynamic for example Post post = RestClient("https://jsonplaceholder.typicode.com").Posts(1).Get()
88
</Description>
9-
<VersionPrefix>4.2.0</VersionPrefix>
9+
<VersionPrefix>4.2.1</VersionPrefix>
1010
<TargetFrameworks>netstandard2.0</TargetFrameworks>
1111
<AssemblyName>DalSoft.RestClient</AssemblyName>
1212
<PackageId>DalSoft.RestClient</PackageId>
1313
<PackageTags>Rest Client;RestClient;REST;Client;JSON;Dynamic;WebApi;HttpClient;Core;iOS;Android;UWP</PackageTags>
1414
<Owners>DalSoft</Owners>
1515
<Authors>DalSoft, joakimjm</Authors>
1616
<PackageReleaseNotes>
17-
* Added RestClient Test extensions Verify and OnVerifyFailed.
18-
* Added RestClient Cast extensions As and Map.
17+
#99 Verify can deadlock in certain situations, because of the use of a local function.
18+
19+
#96 Verify should take an action as well as a Func
1920
</PackageReleaseNotes>
2021
<PackageIconUrl>https://dalsoft.co.uk/images/icon.png</PackageIconUrl>
2122
<PackageProjectUrl>https://restclient.dalsoft.io</PackageProjectUrl>

DalSoft.RestClient/RestClientExtensions.cs

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ dynamic ContinuationFunction(Task<dynamic> task, dynamic state)
6868

6969
return request.ContinueWith
7070
(
71-
continuationFunction:(Func<Task<dynamic>, object, object>)ContinuationFunction,
71+
continuationFunction:(Func<Task<dynamic>, object, object>)((task, state) => ContinuationFunction(task, state)) ,
7272
cancellationToken: cancellationToken,
7373
continuationOptions: continuationOptions,
7474
scheduler:scheduler ?? TaskScheduler.Default,
@@ -105,7 +105,7 @@ dynamic ContinuationFunction(Task<dynamic> task, dynamic state)
105105

106106
return request.ContinueWith
107107
(
108-
continuationFunction: (Func<Task<dynamic>, object, object>)ContinuationFunction,
108+
continuationFunction: (Func<Task<dynamic>, object, object>) ((task, state) => ContinuationFunction(task, state)) ,
109109
cancellationToken: cancellationToken,
110110
continuationOptions: continuationOptions,
111111
scheduler: scheduler ?? TaskScheduler.Default,
@@ -149,7 +149,7 @@ dynamic ContinuationFunction(Task<dynamic> task, dynamic state)
149149

150150
return request.ContinueWith
151151
(
152-
continuationFunction: (Func<Task<dynamic>, object, object>)ContinuationFunction,
152+
continuationFunction: (Func<Task<dynamic>, object, object>) ((task, state) => ContinuationFunction(task, state)) ,
153153
cancellationToken: cancellationToken,
154154
continuationOptions: continuationOptions,
155155
scheduler: scheduler ?? TaskScheduler.Default,
@@ -189,7 +189,42 @@ dynamic ContinuationFunction(Task<dynamic> task, object state)
189189

190190
return request.ContinueWith
191191
(
192-
continuationFunction: (Func<Task<dynamic>, object, object>)ContinuationFunction,
192+
continuationFunction: (Func<Task<dynamic>, object, object>) ((task, state) => ContinuationFunction(task, state)) ,
193+
cancellationToken: cancellationToken,
194+
continuationOptions: continuationOptions,
195+
scheduler: scheduler ?? TaskScheduler.Default,
196+
state: result
197+
);
198+
}
199+
200+
public static Task<dynamic> Act<TResponse>(this Task<dynamic> request,
201+
Action<TResponse, dynamic> onResponse,
202+
CancellationToken cancellationToken = default,
203+
TaskContinuationOptions continuationOptions = TaskContinuationOptions.None,
204+
TaskScheduler scheduler = null) where TResponse : class
205+
{
206+
var result = request.AsyncState ?? request.Result; // In the case of a faulted task and use the first to verify the result
207+
208+
dynamic ContinuationFunction(Task<dynamic> task, object state)
209+
{
210+
if (task.IsFaulted || task.IsCanceled)
211+
{
212+
bool.TryParse(task.Exception?.InnerException?.Data[ThrowOnExceptionKey]?.ToString(), out var throwOnException);
213+
214+
if (throwOnException)
215+
throw task.Exception.ToFlatAggregateException(throwOnException: true);
216+
217+
return null;
218+
}
219+
220+
onResponse?.Invoke(task.Result as TResponse, result);
221+
222+
return state;
223+
}
224+
225+
return request.ContinueWith
226+
(
227+
continuationFunction: (Func<Task<dynamic>, object, object>)((task, state) => ContinuationFunction(task, state)) ,
193228
cancellationToken: cancellationToken,
194229
continuationOptions: continuationOptions,
195230
scheduler: scheduler ?? TaskScheduler.Default,
@@ -220,7 +255,7 @@ T ContinuationFunction(Task<dynamic> task)
220255

221256
return request.ContinueWith
222257
(
223-
continuationFunction: ContinuationFunction,
258+
continuationFunction: task => ContinuationFunction(task),
224259
cancellationToken: cancellationToken,
225260
continuationOptions: continuationOptions,
226261
scheduler: scheduler ?? TaskScheduler.Default
@@ -253,7 +288,7 @@ TTo ContinuationFunction(Task<dynamic> task)
253288

254289
return request.ContinueWith
255290
(
256-
continuationFunction: ContinuationFunction,
291+
continuationFunction: task => ContinuationFunction(task),
257292
cancellationToken: cancellationToken,
258293
continuationOptions: continuationOptions,
259294
scheduler: scheduler ?? TaskScheduler.Default
@@ -286,7 +321,7 @@ TTo ContinuationFunction(Task<dynamic> task)
286321

287322
return request.ContinueWith
288323
(
289-
continuationFunction: ContinuationFunction,
324+
continuationFunction: task => ContinuationFunction(task),
290325
cancellationToken: cancellationToken,
291326
continuationOptions: continuationOptions,
292327
scheduler: scheduler ?? TaskScheduler.Default

0 commit comments

Comments
 (0)