Skip to content

Commit de0ccd6

Browse files
authored
Merge pull request #263 from SimplifyNet/feature/#248
Feature/#248: Added synchronization extensions for the ObservableCollection
2 parents 6c35e18 + c141e51 commit de0ccd6

File tree

4 files changed

+123
-0
lines changed

4 files changed

+123
-0
lines changed
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
using System;
2+
using System.Collections.ObjectModel;
3+
using System.Windows.Data;
4+
5+
namespace Simplify.Wpf.Extensions
6+
{
7+
/// <summary>
8+
/// Provides extensions for the ObservableCollection
9+
/// </summary>
10+
public static class ObservableCollectionExtensions
11+
{
12+
/// <summary>
13+
/// Enables multi-thread synchronization of ObservableCollection instance
14+
/// </summary>
15+
/// <param name="collection">ObservableCollection instance</param>
16+
/// <param name="lockObject"></param>
17+
/// <typeparam name="T"></typeparam>
18+
/// <returns></returns>
19+
public static ObservableCollection<T> EnableSynchronization<T>(this ObservableCollection<T> collection, object? lockObject = null)
20+
{
21+
if (collection is null)
22+
throw new ArgumentNullException(nameof(collection), "ObservableCollection instance is Null");
23+
24+
BindingOperations.EnableCollectionSynchronization(collection, lockObject ?? new object());
25+
return collection;
26+
}
27+
}
28+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
<PropertyGroup>
3+
<TargetFrameworks>net462</TargetFrameworks>
4+
<LangVersion>9.0</LangVersion>
5+
<Nullable>enable</Nullable>
6+
<EmbedUntrackedSources>true</EmbedUntrackedSources>
7+
<IncludeSymbols>true</IncludeSymbols>
8+
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
9+
<OutputPath>bin\Any CPU\$(Configuration)\</OutputPath>
10+
<DocumentationFile>bin\Any CPU\$(Configuration)\$(TargetFramework)\Simplify.Wpf.xml</DocumentationFile>
11+
12+
<Version>1.0</Version>
13+
<PackageReleaseNotes>
14+
ObservableCollection synchronization extensions.
15+
SynchronizedObservableCollection class.
16+
</PackageReleaseNotes>
17+
18+
<Authors>Simplify community</Authors>
19+
<Product>Simplify</Product>
20+
<Description>Extensions for the PresentationFramework</Description>
21+
<Copyright>Licensed under LGPL</Copyright>
22+
<PackageProjectUrl>https://github.com/SimplifyNet/Simplify</PackageProjectUrl>
23+
<PackageIconUrl>https://raw.githubusercontent.com/SimplifyNet/Images/master/Logo.png</PackageIconUrl>
24+
<PublishRepositoryUrl>true</PublishRepositoryUrl>
25+
<PackageTags>.NET WPF</PackageTags>
26+
</PropertyGroup>
27+
<ItemGroup>
28+
<PackageReference Include="Simplify.System" Version="1.5.0" />
29+
</ItemGroup>
30+
<ItemGroup>
31+
<Reference Include="PresentationFramework" />
32+
</ItemGroup>
33+
</Project>
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Collections.ObjectModel;
4+
using Simplify.System;
5+
using Simplify.Wpf.Extensions;
6+
7+
namespace Simplify.Wpf
8+
{
9+
/// <summary>
10+
/// Provides multi-thread synchronized ObservableCollection. Implements IConcurrentResource.
11+
/// </summary>
12+
/// <typeparam name="T">Data type</typeparam>
13+
public class SynchronizedObservableCollection<T> : ObservableCollection<T>, IConcurrentResource
14+
{
15+
private readonly object _locker = new();
16+
17+
/// <summary>
18+
/// Creates instance of SynchronizedObservableCollection.
19+
/// </summary>
20+
public SynchronizedObservableCollection()
21+
{
22+
this.EnableSynchronization(_locker);
23+
}
24+
25+
/// <summary>
26+
/// Creates instance of SynchronizedObservableCollection.
27+
/// </summary>
28+
/// <param name="list"></param>
29+
public SynchronizedObservableCollection(List<T> list) : base(list)
30+
{
31+
this.EnableSynchronization(_locker);
32+
}
33+
34+
/// <summary>
35+
/// Creates instance of SynchronizedObservableCollection.
36+
/// </summary>
37+
/// <param name="collection"></param>
38+
public SynchronizedObservableCollection(IEnumerable<T> collection) : base(collection)
39+
{
40+
this.EnableSynchronization(_locker);
41+
}
42+
43+
/// <summary>
44+
/// Invoke the action concurrently
45+
/// </summary>
46+
/// <param name="action">Action over current collection</param>
47+
public void InvokeConcurrently(Action action)
48+
{
49+
if (action is null) throw new ArgumentNullException(nameof(action));
50+
lock (_locker) action();
51+
}
52+
}
53+
}

src/Simplify.sln

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Simplify.FluentNHibernate.E
137137
EndProject
138138
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Simplify.FluentNHibernate.Examples.Database.IntegrationTests", "Examples\Simplify.FluentNHibernate.Examples.Database.IntegrationTests\Simplify.FluentNHibernate.Examples.Database.IntegrationTests.csproj", "{A772A1FC-2AF8-4411-883D-3646339009BE}"
139139
EndProject
140+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "WPF", "WPF", "{B2CDEA39-00C4-4285-9730-EA6C50011D20}"
141+
EndProject
142+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Simplify.Wpf", "Simplify.Wpf\Simplify.Wpf.csproj", "{0C1DF149-F9ED-471A-8EBF-B212A9CA7C5B}"
143+
EndProject
140144
Global
141145
GlobalSection(SolutionConfigurationPlatforms) = preSolution
142146
Debug|Any CPU = Debug|Any CPU
@@ -323,6 +327,10 @@ Global
323327
{A772A1FC-2AF8-4411-883D-3646339009BE}.Debug|Any CPU.Build.0 = Debug|Any CPU
324328
{A772A1FC-2AF8-4411-883D-3646339009BE}.Release|Any CPU.ActiveCfg = Release|Any CPU
325329
{A772A1FC-2AF8-4411-883D-3646339009BE}.Release|Any CPU.Build.0 = Release|Any CPU
330+
{0C1DF149-F9ED-471A-8EBF-B212A9CA7C5B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
331+
{0C1DF149-F9ED-471A-8EBF-B212A9CA7C5B}.Debug|Any CPU.Build.0 = Debug|Any CPU
332+
{0C1DF149-F9ED-471A-8EBF-B212A9CA7C5B}.Release|Any CPU.ActiveCfg = Release|Any CPU
333+
{0C1DF149-F9ED-471A-8EBF-B212A9CA7C5B}.Release|Any CPU.Build.0 = Release|Any CPU
326334
EndGlobalSection
327335
GlobalSection(SolutionProperties) = preSolution
328336
HideSolutionNode = FALSE
@@ -378,6 +386,7 @@ Global
378386
{09BC064D-3174-4FDE-B87F-0F21BA067A5D} = {2D057C2A-06BD-48F2-A075-B6EC42D39007}
379387
{1A825EB4-13D4-45D0-9925-C6AADC3D47EF} = {2D057C2A-06BD-48F2-A075-B6EC42D39007}
380388
{A772A1FC-2AF8-4411-883D-3646339009BE} = {2D057C2A-06BD-48F2-A075-B6EC42D39007}
389+
{0C1DF149-F9ED-471A-8EBF-B212A9CA7C5B} = {B2CDEA39-00C4-4285-9730-EA6C50011D20}
381390
EndGlobalSection
382391
GlobalSection(ExtensibilityGlobals) = postSolution
383392
SolutionGuid = {466E8FF6-456A-4262-A9ED-5E88DB8DCB08}

0 commit comments

Comments
 (0)