// Copyright (c) Arlo Godfrey. All Rights Reserved. // Licensed under the GNU Lesser General Public License, Version 3.0 with additional terms. // See the LICENSE, LICENSE.LESSER and LICENSE.ADDITIONAL files in the project root for more information. using System; using System.Collections.Generic; using System.Runtime.CompilerServices; using System.Threading; using System.Threading.Tasks; using CommunityToolkit.Diagnostics; using OwlCore.Events; using OwlCore.Remoting; using StrixMusic.Sdk.AppModels; using StrixMusic.Sdk.BaseModels; using StrixMusic.Sdk.CoreModels; using StrixMusic.Sdk.MediaPlayback; namespace StrixMusic.Sdk.Plugins.CoreRemote { /// /// Wraps around a to host data, or receives data given some identifiers. /// [RemoteOptions(RemotingDirection.Bidirectional)] public abstract partial class RemoteCorePlayableCollectionGroupBase : ICorePlayableCollectionGroup { private readonly MemberRemote _memberRemote; private readonly ICorePlayableCollectionGroup? _playableCollectionGroup; private readonly ICoreArtistCollection? _artistCollection; private readonly ICoreAlbumCollection? _albumCollection; private readonly ICorePlaylistCollection? _playlistCollection; private readonly ICoreTrackCollection? _trackCollection; private readonly ICoreImageCollection? _imageCollection; private readonly ICoreUrlCollection? _urlCollection; private readonly IPlayableBase? _playableBase; private string _name = string.Empty; private string? _description; private int _totalAlbumItemsCount; private int _totalArtistItemsCount; private int _totalTrackCount; private int _totalPlaylistItemsCount; private int _totalChildrenCount; private int _totalImageCount; private int _totalUrlCount; private bool _isChangeNameAsyncAvailable; private bool _isChangeDescriptionAsyncAvailable; private bool _isChangeDurationAsyncAvailable; private bool _isPlayAlbumCollectionAsyncAvailable; private bool _isPauseAlbumCollectionAsyncAvailable; private bool _isPlayArtistCollectionAsyncAvailable; private bool _isPauseArtistCollectionAsyncAvailable; private bool _isPlayPlaylistCollectionAsyncAvailable; private bool _isPausePlaylistCollectionAsyncAvailable; private bool _isPlayTrackCollectionAsyncAvailable; private bool _isPauseTrackCollectionAsyncAvailable; private PlaybackState _playbackState; private TimeSpan _duration; private DateTime? _lastPlayed; /// /// Creates a new instance of , for receiving data. /// protected RemoteCorePlayableCollectionGroupBase(string sourceCoreInstanceId, string id) { // These properties are set remotely in the other ctor SourceCoreInstanceId = sourceCoreInstanceId; SourceCore = RemoteCore.GetInstance(sourceCoreInstanceId, RemotingMode.Client); Id = id; _memberRemote = new MemberRemote(this, $"{SourceCoreInstanceId}.{GetType().Name}.{Id}", RemoteCoreMessageHandler.SingletonClient); } /// /// Creates a new instance of and wraps around a for sending data. /// /// The collection to wrap around and remotely interact with. protected RemoteCorePlayableCollectionGroupBase(ICorePlayableCollectionGroup corePlayableCollection) { _playableCollectionGroup = corePlayableCollection; _artistCollection = corePlayableCollection; _albumCollection = corePlayableCollection; _playlistCollection = corePlayableCollection; _trackCollection = corePlayableCollection; _imageCollection = corePlayableCollection; _urlCollection = corePlayableCollection; _playableBase = corePlayableCollection; SourceCoreInstanceId = corePlayableCollection.SourceCore.InstanceId; SourceCore = RemoteCore.GetInstance(SourceCoreInstanceId, RemotingMode.Host); Id = corePlayableCollection.Id; var fullRemoteId = $"{SourceCoreInstanceId}.{GetType().Name}.{Id}"; _memberRemote = new MemberRemote(this, fullRemoteId, RemoteCoreMessageHandler.SingletonHost); Name = corePlayableCollection.Name; Description = corePlayableCollection.Description; PlaybackState = corePlayableCollection.PlaybackState; Duration = corePlayableCollection.Duration; LastPlayed = corePlayableCollection.LastPlayed; AddedAt = corePlayableCollection.AddedAt; TotalTrackCount = corePlayableCollection.TotalTrackCount; TotalArtistItemsCount = corePlayableCollection.TotalArtistItemsCount; TotalAlbumItemsCount = corePlayableCollection.TotalAlbumItemsCount; TotalPlaylistItemsCount = corePlayableCollection.TotalPlaylistItemsCount; TotalChildrenCount = corePlayableCollection.TotalChildrenCount; TotalImageCount = corePlayableCollection.TotalImageCount; TotalUrlCount = corePlayableCollection.TotalUrlCount; IsChangeNameAsyncAvailable = corePlayableCollection.IsChangeNameAsyncAvailable; IsChangeDescriptionAsyncAvailable = corePlayableCollection.IsChangeDescriptionAsyncAvailable; IsChangeDurationAsyncAvailable = corePlayableCollection.IsChangeDurationAsyncAvailable; IsPlayAlbumCollectionAsyncAvailable = corePlayableCollection.IsPlayAlbumCollectionAsyncAvailable; IsPauseAlbumCollectionAsyncAvailable = corePlayableCollection.IsPauseAlbumCollectionAsyncAvailable; IsPlayArtistCollectionAsyncAvailable = corePlayableCollection.IsPlayArtistCollectionAsyncAvailable; IsPauseArtistCollectionAsyncAvailable = corePlayableCollection.IsPauseArtistCollectionAsyncAvailable; IsPlayPlaylistCollectionAsyncAvailable = corePlayableCollection.IsPlayPlaylistCollectionAsyncAvailable; IsPausePlaylistCollectionAsyncAvailable = corePlayableCollection.IsPausePlaylistCollectionAsyncAvailable; IsPlayTrackCollectionAsyncAvailable = corePlayableCollection.IsPlayTrackCollectionAsyncAvailable; IsPauseTrackCollectionAsyncAvailable = corePlayableCollection.IsPauseTrackCollectionAsyncAvailable; AttachEvents(corePlayableCollection); } /// public event EventHandler? PlaybackStateChanged; /// public event EventHandler? NameChanged; /// public event EventHandler? DescriptionChanged; /// public event EventHandler? DurationChanged; /// public event EventHandler? LastPlayedChanged; /// public event EventHandler? IsPlayAlbumCollectionAsyncAvailableChanged; /// public event EventHandler? IsPauseAlbumCollectionAsyncAvailableChanged; /// public event EventHandler? IsPlayArtistCollectionAsyncAvailableChanged; /// public event EventHandler? IsPauseArtistCollectionAsyncAvailableChanged; /// public event EventHandler? IsPlayPlaylistCollectionAsyncAvailableChanged; /// public event EventHandler? IsPausePlaylistCollectionAsyncAvailableChanged; /// public event EventHandler? IsPlayTrackCollectionAsyncAvailableChanged; /// public event EventHandler? IsPauseTrackCollectionAsyncAvailableChanged; /// public event EventHandler? IsChangeNameAsyncAvailableChanged; /// public event EventHandler? IsChangeDescriptionAsyncAvailableChanged; /// public event EventHandler? IsChangeDurationAsyncAvailableChanged; /// public event EventHandler? ImagesCountChanged; /// public event EventHandler? UrlsCountChanged; /// public event EventHandler? PlaylistItemsCountChanged; /// public event EventHandler? TracksCountChanged; /// public event EventHandler? AlbumItemsCountChanged; /// public event EventHandler? ArtistItemsCountChanged; /// public event EventHandler? ChildrenCountChanged; /// public event CollectionChangedEventHandler? TracksChanged; /// public event CollectionChangedEventHandler? PlaylistItemsChanged; /// public event CollectionChangedEventHandler? AlbumItemsChanged; /// public event CollectionChangedEventHandler? ArtistItemsChanged; /// public event CollectionChangedEventHandler? ChildItemsChanged; /// public event CollectionChangedEventHandler? ImagesChanged; /// public event CollectionChangedEventHandler? UrlsChanged; /// /// The instance ID of the /// public string SourceCoreInstanceId { get; set; } /// public ICore SourceCore { get; set; } /// public string Id { get; set; } /// [RemoteProperty] public string Name { get => _name; set { _name = value; NameChanged?.Invoke(this, value); } } /// [RemoteProperty] public string? Description { get => _description; set { _description = value; DescriptionChanged?.Invoke(this, value); } } /// [RemoteProperty] public PlaybackState PlaybackState { get => _playbackState; set { _playbackState = value; PlaybackStateChanged?.Invoke(this, value); } } /// [RemoteProperty] public TimeSpan Duration { get => _duration; set { _duration = value; DurationChanged?.Invoke(this, value); } } /// [RemoteProperty] public DateTime? LastPlayed { get => _lastPlayed; set { _lastPlayed = value; LastPlayedChanged?.Invoke(this, value); } } /// [RemoteProperty] public DateTime? AddedAt { get; set; } /// [RemoteProperty] public int TotalAlbumItemsCount { get => _totalAlbumItemsCount; set { _totalAlbumItemsCount = value; AlbumItemsCountChanged?.Invoke(this, value); } } /// [RemoteProperty] public int TotalArtistItemsCount { get => _totalArtistItemsCount; set { _totalArtistItemsCount = value; ArtistItemsCountChanged?.Invoke(this, value); } } /// [RemoteProperty] public int TotalTrackCount { get => _totalTrackCount; set { _totalTrackCount = value; TracksCountChanged?.Invoke(this, value); } } /// [RemoteProperty] public int TotalPlaylistItemsCount { get => _totalPlaylistItemsCount; set { _totalPlaylistItemsCount = value; PlaylistItemsCountChanged?.Invoke(this, value); } } /// [RemoteProperty] public int TotalChildrenCount { get => _totalChildrenCount; internal set { _totalChildrenCount = value; ChildrenCountChanged?.Invoke(this, value); } } /// [RemoteProperty] public int TotalImageCount { get => _totalImageCount; internal set { _totalImageCount = value; ImagesCountChanged?.Invoke(this, value); } } /// [RemoteProperty] public int TotalUrlCount { get => _totalUrlCount; internal set { _totalUrlCount = value; UrlsCountChanged?.Invoke(this, value); } } /// [RemoteProperty] public bool IsPlayAlbumCollectionAsyncAvailable { get => _isPlayAlbumCollectionAsyncAvailable; set { _isPlayAlbumCollectionAsyncAvailable = value; IsPlayAlbumCollectionAsyncAvailableChanged?.Invoke(this, value); } } /// [RemoteProperty] public bool IsPauseAlbumCollectionAsyncAvailable { get => _isPauseAlbumCollectionAsyncAvailable; set { _isPauseAlbumCollectionAsyncAvailable = value; IsPauseAlbumCollectionAsyncAvailableChanged?.Invoke(this, value); } } /// [RemoteProperty] public bool IsPlayArtistCollectionAsyncAvailable { get => _isPlayArtistCollectionAsyncAvailable; set { _isPlayArtistCollectionAsyncAvailable = value; IsPlayArtistCollectionAsyncAvailableChanged?.Invoke(this, value); } } /// [RemoteProperty] public bool IsPauseArtistCollectionAsyncAvailable { get => _isPauseArtistCollectionAsyncAvailable; set { _isPauseArtistCollectionAsyncAvailable = value; IsPauseArtistCollectionAsyncAvailableChanged?.Invoke(this, value); } } /// [RemoteProperty] public bool IsPlayPlaylistCollectionAsyncAvailable { get => _isPlayPlaylistCollectionAsyncAvailable; set { _isPlayPlaylistCollectionAsyncAvailable = value; IsPlayPlaylistCollectionAsyncAvailableChanged?.Invoke(this, value); } } /// [RemoteProperty] public bool IsPausePlaylistCollectionAsyncAvailable { get => _isPausePlaylistCollectionAsyncAvailable; set { _isPausePlaylistCollectionAsyncAvailable = value; IsPausePlaylistCollectionAsyncAvailableChanged?.Invoke(this, value); } } /// [RemoteProperty] public bool IsPlayTrackCollectionAsyncAvailable { get => _isPlayTrackCollectionAsyncAvailable; set { _isPlayTrackCollectionAsyncAvailable = value; IsPlayTrackCollectionAsyncAvailableChanged?.Invoke(this, value); } } /// [RemoteProperty] public bool IsPauseTrackCollectionAsyncAvailable { get => _isPauseTrackCollectionAsyncAvailable; set { _isPauseTrackCollectionAsyncAvailable = value; IsPauseTrackCollectionAsyncAvailableChanged?.Invoke(this, value); } } /// [RemoteProperty] public bool IsChangeNameAsyncAvailable { get => _isChangeNameAsyncAvailable; set { _isChangeNameAsyncAvailable = value; IsChangeNameAsyncAvailableChanged?.Invoke(this, value); } } /// [RemoteProperty] public bool IsChangeDescriptionAsyncAvailable { get => _isChangeDescriptionAsyncAvailable; set { _isChangeDescriptionAsyncAvailable = value; IsChangeDescriptionAsyncAvailableChanged?.Invoke(this, value); } } /// [RemoteProperty] public bool IsChangeDurationAsyncAvailable { get => _isChangeDurationAsyncAvailable; set { _isChangeDurationAsyncAvailable = value; IsChangeDurationAsyncAvailableChanged?.Invoke(this, value); } } /// [RemoteMethod] public Task IsAddChildAvailableAsync(int index, CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(IsAddChildAvailableAsync)}.{index}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_playableCollectionGroup, nameof(_playableCollectionGroup)); var res = await _playableCollectionGroup.IsAddChildAvailableAsync(index); return await _memberRemote.PublishDataAsync(methodCallToken, res); } if (_memberRemote.Mode == RemotingMode.Client) return await _memberRemote.ReceiveDataAsync(methodCallToken); return ThrowHelper.ThrowArgumentOutOfRangeException("Invalid remoting mode"); }); /// [RemoteMethod] public Task IsAddPlaylistItemAvailableAsync(int index, CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(IsAddPlaylistItemAvailableAsync)}.{index}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_playlistCollection, nameof(_playlistCollection)); var res = await _playlistCollection.IsAddPlaylistItemAvailableAsync(index); return await _memberRemote.PublishDataAsync(methodCallToken, res); } if (_memberRemote.Mode == RemotingMode.Client) return await _memberRemote.ReceiveDataAsync(methodCallToken); return ThrowHelper.ThrowArgumentOutOfRangeException("Invalid remoting mode"); }); /// [RemoteMethod] public Task IsAddTrackAvailableAsync(int index, CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(IsAddTrackAvailableAsync)}.{index}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_trackCollection, nameof(_trackCollection)); var res = await _trackCollection.IsAddTrackAvailableAsync(index); return await _memberRemote.PublishDataAsync(methodCallToken, res); } if (_memberRemote.Mode == RemotingMode.Client) return await _memberRemote.ReceiveDataAsync(methodCallToken); return ThrowHelper.ThrowArgumentOutOfRangeException("Invalid remoting mode"); }); /// [RemoteMethod] public Task IsAddArtistItemAvailableAsync(int index, CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(IsAddArtistItemAvailableAsync)}.{index}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_artistCollection, nameof(_artistCollection)); var res = await _artistCollection.IsAddArtistItemAvailableAsync(index); return await _memberRemote.PublishDataAsync(methodCallToken, res); } if (_memberRemote.Mode == RemotingMode.Client) return await _memberRemote.ReceiveDataAsync(methodCallToken); return ThrowHelper.ThrowArgumentOutOfRangeException("Invalid remoting mode"); }); /// [RemoteMethod] public Task IsAddAlbumItemAvailableAsync(int index, CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(IsAddAlbumItemAvailableAsync)}.{index}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_albumCollection, nameof(_albumCollection)); var res = await _albumCollection.IsAddAlbumItemAvailableAsync(index); return await _memberRemote.PublishDataAsync(methodCallToken, res); } if (_memberRemote.Mode == RemotingMode.Client) return await _memberRemote.ReceiveDataAsync(methodCallToken); return ThrowHelper.ThrowArgumentOutOfRangeException("Invalid remoting mode"); }); /// [RemoteMethod] public Task IsAddImageAvailableAsync(int index, CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(IsAddImageAvailableAsync)}.{index}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_imageCollection, nameof(_imageCollection)); var res = await _imageCollection.IsAddImageAvailableAsync(index); return await _memberRemote.PublishDataAsync(methodCallToken, res); } if (_memberRemote.Mode == RemotingMode.Client) return await _memberRemote.ReceiveDataAsync(methodCallToken); return ThrowHelper.ThrowArgumentOutOfRangeException("Invalid remoting mode"); }); /// [RemoteMethod] public Task IsAddUrlAvailableAsync(int index, CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(IsAddUrlAvailableAsync)}.{index}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_urlCollection, nameof(_urlCollection)); var res = await _urlCollection.IsAddUrlAvailableAsync(index); return await _memberRemote.PublishDataAsync(methodCallToken, res); } if (_memberRemote.Mode == RemotingMode.Client) return await _memberRemote.ReceiveDataAsync(methodCallToken); return ThrowHelper.ThrowArgumentOutOfRangeException("Invalid remoting mode"); }); /// [RemoteMethod] public Task IsRemoveTrackAvailableAsync(int index, CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(IsRemoveTrackAvailableAsync)}.{index}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_trackCollection, nameof(_trackCollection)); var res = await _trackCollection.IsRemoveTrackAvailableAsync(index); return await _memberRemote.PublishDataAsync(methodCallToken, res); } if (_memberRemote.Mode == RemotingMode.Client) return await _memberRemote.ReceiveDataAsync(methodCallToken); return ThrowHelper.ThrowArgumentOutOfRangeException("Invalid remoting mode"); }); /// [RemoteMethod] public Task IsRemoveImageAvailableAsync(int index, CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(IsRemoveImageAvailableAsync)}.{index}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_imageCollection, nameof(_imageCollection)); var res = await _imageCollection.IsRemoveImageAvailableAsync(index); return await _memberRemote.PublishDataAsync(methodCallToken, res); } if (_memberRemote.Mode == RemotingMode.Client) return await _memberRemote.ReceiveDataAsync(methodCallToken); return ThrowHelper.ThrowArgumentOutOfRangeException("Invalid remoting mode"); }); /// [RemoteMethod] public Task IsRemoveUrlAvailableAsync(int index, CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(IsRemoveUrlAvailableAsync)}.{index}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_urlCollection, nameof(_urlCollection)); var res = await _urlCollection.IsRemoveUrlAvailableAsync(index); return await _memberRemote.PublishDataAsync(methodCallToken, res); } if (_memberRemote.Mode == RemotingMode.Client) return await _memberRemote.ReceiveDataAsync(methodCallToken); return ThrowHelper.ThrowArgumentOutOfRangeException("Invalid remoting mode"); }); /// [RemoteMethod] public Task IsRemovePlaylistItemAvailableAsync(int index, CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(IsRemovePlaylistItemAvailableAsync)}.{index}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_playlistCollection, nameof(_playlistCollection)); var res = await _playlistCollection.IsRemovePlaylistItemAvailableAsync(index); return await _memberRemote.PublishDataAsync(methodCallToken, res); } if (_memberRemote.Mode == RemotingMode.Client) return await _memberRemote.ReceiveDataAsync(methodCallToken); return ThrowHelper.ThrowArgumentOutOfRangeException("Invalid remoting mode"); }); /// [RemoteMethod] public Task IsRemoveAlbumItemAvailableAsync(int index, CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(IsRemoveAlbumItemAvailableAsync)}.{index}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_albumCollection, nameof(_albumCollection)); var res = await _albumCollection.IsRemoveAlbumItemAvailableAsync(index); return await _memberRemote.PublishDataAsync(methodCallToken, res); } if (_memberRemote.Mode == RemotingMode.Client) return await _memberRemote.ReceiveDataAsync(methodCallToken); return ThrowHelper.ThrowArgumentOutOfRangeException("Invalid remoting mode"); }); /// [RemoteMethod] public Task IsRemoveArtistItemAvailableAsync(int index, CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(IsRemoveArtistItemAvailableAsync)}.{index}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_artistCollection, nameof(_artistCollection)); var res = await _artistCollection.IsRemoveArtistItemAvailableAsync(index); return await _memberRemote.PublishDataAsync(methodCallToken, res); } if (_memberRemote.Mode == RemotingMode.Client) return await _memberRemote.ReceiveDataAsync(methodCallToken); return ThrowHelper.ThrowArgumentOutOfRangeException("Invalid remoting mode"); }); /// [RemoteMethod] public Task IsRemoveChildAvailableAsync(int index, CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(IsRemoveChildAvailableAsync)}.{index}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_playableCollectionGroup, nameof(_playableCollectionGroup)); var res = await _playableCollectionGroup.IsRemoveChildAvailableAsync(index); return await _memberRemote.PublishDataAsync(methodCallToken, res); } if (_memberRemote.Mode == RemotingMode.Client) return await _memberRemote.ReceiveDataAsync(methodCallToken); return ThrowHelper.ThrowArgumentOutOfRangeException("Invalid remoting mode"); }); /// [RemoteMethod] public Task ChangeDescriptionAsync(string? description, CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(ChangeDescriptionAsync)}.{description}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_playableBase, nameof(_playableBase)); await _playableBase.ChangeDescriptionAsync(description); await _memberRemote.RemoteReleaseAsync(methodCallToken); } if (_memberRemote.Mode == RemotingMode.Client) { await _memberRemote.RemoteWaitAsync(methodCallToken); } }); /// [RemoteMethod] public Task ChangeDurationAsync(TimeSpan duration, CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(ChangeDurationAsync)}.{duration}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_playableBase, nameof(_playableBase)); await _playableBase.ChangeDurationAsync(duration); await _memberRemote.RemoteReleaseAsync(methodCallToken); } if (_memberRemote.Mode == RemotingMode.Client) { await _memberRemote.RemoteWaitAsync(methodCallToken); } }); /// [RemoteMethod] public Task ChangeNameAsync(string name, CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(ChangeNameAsync)}.{name}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_playableBase, nameof(_playableBase)); await _playableBase.ChangeNameAsync(name); await _memberRemote.RemoteReleaseAsync(methodCallToken); } if (_memberRemote.Mode == RemotingMode.Client) { await _memberRemote.RemoteWaitAsync(methodCallToken); } }); /// A cancellation token that may be used to cancel the ongoing task. /// [RemoteMethod] public Task PauseAlbumCollectionAsync(CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(PauseAlbumCollectionAsync)}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_albumCollection, nameof(_albumCollection)); await _albumCollection.PauseAlbumCollectionAsync(); await _memberRemote.RemoteReleaseAsync(methodCallToken); } if (_memberRemote.Mode == RemotingMode.Client) { await _memberRemote.RemoteWaitAsync(methodCallToken); } }); /// A cancellation token that may be used to cancel the ongoing task. /// [RemoteMethod] public Task PlayAlbumCollectionAsync(CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(PlayAlbumCollectionAsync)}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_albumCollection, nameof(_albumCollection)); await _albumCollection.PlayAlbumCollectionAsync(); await _memberRemote.RemoteReleaseAsync(methodCallToken); } if (_memberRemote.Mode == RemotingMode.Client) { await _memberRemote.RemoteWaitAsync(methodCallToken); } }); /// A cancellation token that may be used to cancel the ongoing task. /// [RemoteMethod] public Task PauseArtistCollectionAsync(CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(PauseArtistCollectionAsync)}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_artistCollection, nameof(_artistCollection)); await _artistCollection.PauseArtistCollectionAsync(); await _memberRemote.RemoteReleaseAsync(methodCallToken); } if (_memberRemote.Mode == RemotingMode.Client) { await _memberRemote.RemoteWaitAsync(methodCallToken); } }); /// A cancellation token that may be used to cancel the ongoing task. /// [RemoteMethod] public Task PlayArtistCollectionAsync(CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(PlayArtistCollectionAsync)}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_artistCollection, nameof(_artistCollection)); await _artistCollection.PlayArtistCollectionAsync(); await _memberRemote.RemoteReleaseAsync(methodCallToken); } if (_memberRemote.Mode == RemotingMode.Client) { await _memberRemote.RemoteWaitAsync(methodCallToken); } }); /// A cancellation token that may be used to cancel the ongoing task. /// [RemoteMethod] public Task PausePlaylistCollectionAsync(CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(PausePlaylistCollectionAsync)}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_playlistCollection, nameof(_playlistCollection)); await _playlistCollection.PausePlaylistCollectionAsync(); await _memberRemote.RemoteReleaseAsync(methodCallToken); } if (_memberRemote.Mode == RemotingMode.Client) { await _memberRemote.RemoteWaitAsync(methodCallToken); } }); /// A cancellation token that may be used to cancel the ongoing task. /// [RemoteMethod] public Task PlayPlaylistCollectionAsync(CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(PlayPlaylistCollectionAsync)}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_playlistCollection, nameof(_playlistCollection)); await _playlistCollection.PlayPlaylistCollectionAsync(); await _memberRemote.RemoteReleaseAsync(methodCallToken); } if (_memberRemote.Mode == RemotingMode.Client) { await _memberRemote.RemoteWaitAsync(methodCallToken); } }); /// A cancellation token that may be used to cancel the ongoing task. /// [RemoteMethod] public Task PauseTrackCollectionAsync(CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(PauseTrackCollectionAsync)}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_trackCollection, nameof(_trackCollection)); await _trackCollection.PauseTrackCollectionAsync(); await _memberRemote.RemoteReleaseAsync(methodCallToken); } if (_memberRemote.Mode == RemotingMode.Client) { await _memberRemote.RemoteWaitAsync(methodCallToken); } }); /// A cancellation token that may be used to cancel the ongoing task. /// [RemoteMethod] public Task PlayTrackCollectionAsync(CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(PlayTrackCollectionAsync)}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_trackCollection, nameof(_trackCollection)); await _trackCollection.PlayTrackCollectionAsync(); await _memberRemote.RemoteReleaseAsync(methodCallToken); } if (_memberRemote.Mode == RemotingMode.Client) { await _memberRemote.RemoteWaitAsync(methodCallToken); } }); /// [RemoteMethod] public Task PlayAlbumCollectionAsync(ICoreAlbumCollectionItem albumItem, CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(PlayAlbumCollectionAsync)}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_albumCollection, nameof(_albumCollection)); await _albumCollection.PlayAlbumCollectionAsync(albumItem); await _memberRemote.RemoteReleaseAsync(methodCallToken); } if (_memberRemote.Mode == RemotingMode.Client) { await _memberRemote.RemoteWaitAsync(methodCallToken); } }); /// A cancellation token that may be used to cancel the ongoing task. /// [RemoteMethod] public Task PlayPlayableCollectionGroupAsync(CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(PlayPlayableCollectionGroupAsync)}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_playableCollectionGroup, nameof(_playableCollectionGroup)); await _playableCollectionGroup.PlayPlayableCollectionGroupAsync(); await _memberRemote.RemoteReleaseAsync(methodCallToken); } if (_memberRemote.Mode == RemotingMode.Client) { await _memberRemote.RemoteWaitAsync(methodCallToken); } }); /// A cancellation token that may be used to cancel the ongoing task. /// [RemoteMethod] public Task PausePlayableCollectionGroupAsync(CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(PausePlayableCollectionGroupAsync)}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_playableCollectionGroup, nameof(_playableCollectionGroup)); await _playableCollectionGroup.PausePlayableCollectionGroupAsync(); await _memberRemote.RemoteReleaseAsync(methodCallToken); } if (_memberRemote.Mode == RemotingMode.Client) { await _memberRemote.RemoteWaitAsync(methodCallToken); } }); /// [RemoteMethod] public Task PlayPlaylistCollectionAsync(ICorePlaylistCollectionItem playlistItem, CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(PlayPlaylistCollectionAsync)}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_playlistCollection, nameof(_playlistCollection)); await _playlistCollection.PlayPlaylistCollectionAsync(playlistItem); await _memberRemote.RemoteReleaseAsync(methodCallToken); } if (_memberRemote.Mode == RemotingMode.Client) { await _memberRemote.RemoteWaitAsync(methodCallToken); } }); /// [RemoteMethod] public Task PlayArtistCollectionAsync(ICoreArtistCollectionItem artistItem, CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(PlayArtistCollectionAsync)}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_artistCollection, nameof(_artistCollection)); await _artistCollection.PlayArtistCollectionAsync(artistItem); await _memberRemote.RemoteReleaseAsync(methodCallToken); } if (_memberRemote.Mode == RemotingMode.Client) { await _memberRemote.RemoteWaitAsync(methodCallToken); } }); /// [RemoteMethod] public Task PlayPlayableCollectionGroupAsync(ICorePlayableCollectionGroup collectionGroup, CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(PlayPlayableCollectionGroupAsync)}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_playableCollectionGroup, nameof(_playableCollectionGroup)); await _playableCollectionGroup.PlayPlayableCollectionGroupAsync(collectionGroup); await _memberRemote.RemoteReleaseAsync(methodCallToken); } if (_memberRemote.Mode == RemotingMode.Client) { await _memberRemote.RemoteWaitAsync(methodCallToken); } }); /// [RemoteMethod] public Task PlayTrackCollectionAsync(ICoreTrack track, CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(PlayTrackCollectionAsync)}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_trackCollection, nameof(_trackCollection)); await _trackCollection.PlayTrackCollectionAsync(track); await _memberRemote.RemoteReleaseAsync(methodCallToken); } if (_memberRemote.Mode == RemotingMode.Client) { await _memberRemote.RemoteWaitAsync(methodCallToken); } }); /// [RemoteMethod] public async IAsyncEnumerable GetChildrenAsync(int limit, int offset, [EnumeratorCancellation] CancellationToken cancellationToken = default) { var callToken = $"{nameof(GetChildrenAsync)}.{limit}.{offset}"; if (_memberRemote.Mode == RemotingMode.Client) { var res = await _memberRemote.ReceiveDataAsync(callToken); if (res is null) yield break; foreach (var item in res) yield return item; yield break; } if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_playableCollectionGroup, nameof(_playableCollectionGroup)); await foreach (var item in _playableCollectionGroup.GetChildrenAsync(limit, offset)) yield return item; } } /// [RemoteMethod] public async IAsyncEnumerable GetPlaylistItemsAsync(int limit, int offset, [EnumeratorCancellation] CancellationToken cancellationToken = default) { var callToken = $"{nameof(GetPlaylistItemsAsync)}.{limit}.{offset}"; if (_memberRemote.Mode == RemotingMode.Client) { var res = await _memberRemote.ReceiveDataAsync(callToken); if (res is null) yield break; foreach (var item in res) yield return item; yield break; } if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_playlistCollection, nameof(_playlistCollection)); await foreach (var item in _playlistCollection.GetPlaylistItemsAsync(limit, offset)) yield return item; } } /// [RemoteMethod] public async IAsyncEnumerable GetAlbumItemsAsync(int limit, int offset, [EnumeratorCancellation] CancellationToken cancellationToken = default) { var callToken = $"{nameof(GetAlbumItemsAsync)}.{limit}.{offset}"; if (_memberRemote.Mode == RemotingMode.Client) { var res = await _memberRemote.ReceiveDataAsync(callToken); if (res is null) yield break; foreach (var item in res) yield return item; yield break; } if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_albumCollection, nameof(_albumCollection)); await foreach (var item in _albumCollection.GetAlbumItemsAsync(limit, offset)) yield return item; } } /// [RemoteMethod] public async IAsyncEnumerable GetArtistItemsAsync(int limit, int offset, [EnumeratorCancellation] CancellationToken cancellationToken = default) { var callToken = $"{nameof(GetArtistItemsAsync)}.{limit}.{offset}"; if (_memberRemote.Mode == RemotingMode.Client) { var res = await _memberRemote.ReceiveDataAsync(callToken); if (res is null) yield break; foreach (var item in res) yield return item; yield break; } if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_artistCollection, nameof(_artistCollection)); await foreach (var item in _artistCollection.GetArtistItemsAsync(limit, offset)) yield return item; } } /// [RemoteMethod] public async IAsyncEnumerable GetTracksAsync(int limit, int offset, [EnumeratorCancellation] CancellationToken cancellationToken = default) { var callToken = $"{nameof(GetTracksAsync)}.{limit}.{offset}"; if (_memberRemote.Mode == RemotingMode.Client) { var res = await _memberRemote.ReceiveDataAsync(callToken); if (res is null) yield break; foreach (var item in res) yield return item; yield break; } if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_trackCollection, nameof(_trackCollection)); await foreach (var item in _trackCollection.GetTracksAsync(limit, offset)) yield return item; } } /// [RemoteMethod] public async IAsyncEnumerable GetImagesAsync(int limit, int offset, [EnumeratorCancellation] CancellationToken cancellationToken = default) { var callToken = $"{nameof(GetImagesAsync)}.{limit}.{offset}"; if (_memberRemote.Mode == RemotingMode.Client) { var res = await _memberRemote.ReceiveDataAsync(callToken); if (res is null) yield break; foreach (var item in res) yield return item; yield break; } if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_imageCollection, nameof(_imageCollection)); await foreach (var item in _imageCollection.GetImagesAsync(limit, offset)) yield return item; } } /// [RemoteMethod] public async IAsyncEnumerable GetUrlsAsync(int limit, int offset, [EnumeratorCancellation] CancellationToken cancellationToken = default) { var callToken = $"{nameof(GetUrlsAsync)}.{limit}.{offset}"; if (_memberRemote.Mode == RemotingMode.Client) { var res = await _memberRemote.ReceiveDataAsync(callToken); if (res is null) yield break; foreach (var item in res) yield return item; yield break; } if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_urlCollection, nameof(_urlCollection)); await foreach (var item in _urlCollection.GetUrlsAsync(limit, offset)) yield return item; } } /// /// /// Implementations of passed to this method must be in the SDK for deserialization to work. /// Typically this is a RemoteCore model or an implementation of . /// [RemoteMethod] public Task AddTrackAsync(ICoreTrack track, int index, CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(AddTrackAsync)}.{index}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_trackCollection, nameof(_trackCollection)); await _trackCollection.AddTrackAsync(track, index); await _memberRemote.RemoteReleaseAsync(methodCallToken); } if (_memberRemote.Mode == RemotingMode.Client) { await _memberRemote.RemoteWaitAsync(methodCallToken); } }); /// /// /// Implementations of passed to this method must be in the SDK for deserialization to work. /// Typically this is a RemoteCore model or an implementation of . /// [RemoteMethod] public Task AddArtistItemAsync(ICoreArtistCollectionItem artist, int index, CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(AddArtistItemAsync)}.{index}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_artistCollection, nameof(_artistCollection)); await _artistCollection.AddArtistItemAsync(artist, index); await _memberRemote.RemoteReleaseAsync(methodCallToken); } if (_memberRemote.Mode == RemotingMode.Client) { await _memberRemote.RemoteWaitAsync(methodCallToken); } }); /// /// /// Implementations of passed to this method must be in the SDK for deserialization to work. /// Typically this is a RemoteCore model or an implementation of . /// [RemoteMethod] public Task AddAlbumItemAsync(ICoreAlbumCollectionItem album, int index, CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(AddAlbumItemAsync)}.{index}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_albumCollection, nameof(_albumCollection)); await _albumCollection.AddAlbumItemAsync(album, index); await _memberRemote.RemoteReleaseAsync(methodCallToken); } if (_memberRemote.Mode == RemotingMode.Client) { await _memberRemote.RemoteWaitAsync(methodCallToken); } }); /// /// /// Implementations of passed to this method must be in the SDK for deserialization to work. /// Typically this is a RemoteCore model or an implementation of . /// [RemoteMethod] public Task AddPlaylistItemAsync(ICorePlaylistCollectionItem playlist, int index, CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(AddPlaylistItemAsync)}.{index}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_playlistCollection, nameof(_playlistCollection)); await _playlistCollection.AddPlaylistItemAsync(playlist, index); await _memberRemote.RemoteReleaseAsync(methodCallToken); } if (_memberRemote.Mode == RemotingMode.Client) { await _memberRemote.RemoteWaitAsync(methodCallToken); } }); /// /// /// Implementations of passed to this method must be in the SDK for deserialization to work. /// Typically this is a RemoteCore model or an implementation of . /// [RemoteMethod] public Task AddChildAsync(ICorePlayableCollectionGroup child, int index, CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(AddChildAsync)}.{index}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_playableCollectionGroup, nameof(_playableCollectionGroup)); await _playableCollectionGroup.AddChildAsync(child, index); await _memberRemote.RemoteReleaseAsync(methodCallToken); } if (_memberRemote.Mode == RemotingMode.Client) { await _memberRemote.RemoteWaitAsync(methodCallToken); } }); /// /// /// Implementations of passed to this method must be in the SDK for deserialization to work. /// Typically this is a RemoteCore model or an implementation of . /// [RemoteMethod] public Task AddImageAsync(ICoreImage image, int index, CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(AddImageAsync)}.{index}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_imageCollection, nameof(_imageCollection)); await _imageCollection.AddImageAsync(image, index); await _memberRemote.RemoteReleaseAsync(methodCallToken); } if (_memberRemote.Mode == RemotingMode.Client) { await _memberRemote.RemoteWaitAsync(methodCallToken); } }); /// /// /// Implementations of passed to this method must be in the SDK for deserialization to work. /// Typically this is a RemoteCore model or an implementation of . /// [RemoteMethod] public Task AddUrlAsync(ICoreUrl url, int index, CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(AddUrlAsync)}.{index}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_urlCollection, nameof(_urlCollection)); await _urlCollection.AddUrlAsync(url, index); await _memberRemote.RemoteReleaseAsync(methodCallToken); } if (_memberRemote.Mode == RemotingMode.Client) { await _memberRemote.RemoteWaitAsync(methodCallToken); } }); /// [RemoteMethod] public Task RemoveTrackAsync(int index, CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(RemoveTrackAsync)}.{index}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_trackCollection, nameof(_trackCollection)); await _trackCollection.RemoveTrackAsync(index); await _memberRemote.RemoteReleaseAsync(methodCallToken); } if (_memberRemote.Mode == RemotingMode.Client) { await _memberRemote.RemoteWaitAsync(methodCallToken); } }); /// [RemoteMethod] public Task RemoveArtistItemAsync(int index, CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(RemoveArtistItemAsync)}.{index}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_artistCollection, nameof(_artistCollection)); await _artistCollection.RemoveArtistItemAsync(index); await _memberRemote.RemoteReleaseAsync(methodCallToken); } if (_memberRemote.Mode == RemotingMode.Client) { await _memberRemote.RemoteWaitAsync(methodCallToken); } }); /// [RemoteMethod] public Task RemoveAlbumItemAsync(int index, CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(RemoveAlbumItemAsync)}.{index}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_albumCollection, nameof(_albumCollection)); await _albumCollection.RemoveAlbumItemAsync(index); await _memberRemote.RemoteReleaseAsync(methodCallToken); } if (_memberRemote.Mode == RemotingMode.Client) { await _memberRemote.RemoteWaitAsync(methodCallToken); } }); /// [RemoteMethod] public Task RemovePlaylistItemAsync(int index, CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(RemovePlaylistItemAsync)}.{index}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_playlistCollection, nameof(_playlistCollection)); await _playlistCollection.RemovePlaylistItemAsync(index); await _memberRemote.RemoteReleaseAsync(methodCallToken); } if (_memberRemote.Mode == RemotingMode.Client) { await _memberRemote.RemoteWaitAsync(methodCallToken); } }); /// [RemoteMethod] public Task RemoveChildAsync(int index, CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(RemoveChildAsync)}.{index}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_playableCollectionGroup, nameof(_playableCollectionGroup)); await _playableCollectionGroup.RemoveChildAsync(index); await _memberRemote.RemoteReleaseAsync(methodCallToken); } if (_memberRemote.Mode == RemotingMode.Client) { await _memberRemote.RemoteWaitAsync(methodCallToken); } }); /// [RemoteMethod] public Task RemoveImageAsync(int index, CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(RemoveImageAsync)}.{index}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_imageCollection, nameof(_imageCollection)); await _imageCollection.RemoveImageAsync(index); await _memberRemote.RemoteReleaseAsync(methodCallToken); } if (_memberRemote.Mode == RemotingMode.Client) { await _memberRemote.RemoteWaitAsync(methodCallToken); } }); /// [RemoteMethod] public Task RemoveUrlAsync(int index, CancellationToken cancellationToken = default) => Task.Run(async () => { var methodCallToken = $"{nameof(RemoveUrlAsync)}.{index}"; if (_memberRemote.Mode == RemotingMode.Host) { Guard.IsNotNull(_urlCollection, nameof(_urlCollection)); await _urlCollection.RemoveUrlAsync(index); await _memberRemote.RemoteReleaseAsync(methodCallToken); } if (_memberRemote.Mode == RemotingMode.Client) { await _memberRemote.RemoteWaitAsync(methodCallToken); } }); /// [RemoteMethod] public ValueTask DisposeAsync() => new ValueTask(Task.Run(async () => { await _memberRemote.RemoteWaitAsync(nameof(DisposeAsync)); _memberRemote.Dispose(); })); } }