Skip to content

Commit 69d3694

Browse files
Edward Millermattleibow
Edward Miller
authored andcommitted
use semaphore instead of lock
1 parent f1faddd commit 69d3694

File tree

3 files changed

+21
-11
lines changed

3 files changed

+21
-11
lines changed

src/Controls/src/Core/ImageSource.cs

+15-5
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace Microsoft.Maui.Controls
1111
[System.ComponentModel.TypeConverter(typeof(ImageSourceConverter))]
1212
public abstract partial class ImageSource : Element
1313
{
14-
readonly object _synchandle = new object();
14+
readonly SemaphoreSlim _cancellationTokenSourceLock = new(1, 1);
1515
CancellationTokenSource _cancellationTokenSource;
1616

1717
TaskCompletionSource<bool> _completionSource;
@@ -121,7 +121,7 @@ public static implicit operator ImageSource(Uri uri)
121121
return FromUri(uri);
122122
}
123123

124-
private protected void OnLoadingCompleted(bool cancelled)
124+
private protected async Task OnLoadingCompleted(bool cancelled)
125125
{
126126
if (!IsLoading || _completionSource == null)
127127
return;
@@ -130,18 +130,28 @@ private protected void OnLoadingCompleted(bool cancelled)
130130
if (tcs != null)
131131
tcs.SetResult(cancelled);
132132

133-
lock (_synchandle)
133+
await _cancellationTokenSourceLock.WaitAsync();
134+
try
134135
{
135136
CancellationTokenSource = null;
136137
}
138+
finally
139+
{
140+
_cancellationTokenSourceLock.Release();
141+
}
137142
}
138143

139-
private protected void OnLoadingStarted()
144+
private protected async Task OnLoadingStarted()
140145
{
141-
lock (_synchandle)
146+
await _cancellationTokenSourceLock.WaitAsync();
147+
try
142148
{
143149
CancellationTokenSource = new CancellationTokenSource();
144150
}
151+
finally
152+
{
153+
_cancellationTokenSourceLock.Release();
154+
}
145155
}
146156

147157
protected void OnSourceChanged()

src/Controls/src/Core/StreamImageSource.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,17 @@ async Task<Stream> IStreamImageSource.GetStreamAsync(CancellationToken userToken
3535
if (IsEmpty)
3636
return null;
3737

38-
OnLoadingStarted();
38+
await OnLoadingStarted();
3939
userToken.Register(CancellationTokenSource.Cancel);
4040
Stream stream = null;
4141
try
4242
{
4343
stream = await Stream(CancellationTokenSource.Token);
44-
OnLoadingCompleted(false);
44+
await OnLoadingCompleted(false);
4545
}
4646
catch (OperationCanceledException)
4747
{
48-
OnLoadingCompleted(true);
48+
await OnLoadingCompleted(true);
4949
throw;
5050
}
5151
return stream;

src/Controls/src/Core/UriImageSource.cs

+3-3
Original file line numberDiff line numberDiff line change
@@ -56,18 +56,18 @@ async Task<Stream> IStreamImageSource.GetStreamAsync(CancellationToken userToken
5656
if (IsEmpty)
5757
return null;
5858

59-
OnLoadingStarted();
59+
await OnLoadingStarted();
6060
userToken.Register(CancellationTokenSource.Cancel);
6161
Stream stream;
6262

6363
try
6464
{
6565
stream = await GetStreamAsync(Uri, CancellationTokenSource.Token);
66-
OnLoadingCompleted(false);
66+
await OnLoadingCompleted(false);
6767
}
6868
catch (OperationCanceledException)
6969
{
70-
OnLoadingCompleted(true);
70+
await OnLoadingCompleted(true);
7171
throw;
7272
}
7373
catch (Exception ex)

0 commit comments

Comments
 (0)