我订阅了下面的事件,我想知道下面两个示例之间的区别是什么,我需要取消订阅吗?我使用的库是Binance.Net by JKorf。
public event Action<Exception> Exception
{
add => subscription.Exception += value;
remove => subscription.Exception -= value;
}
示例1
// Subscribe
subscription.Data.Exception += PortfolioService_Exception;
// Unsubscribe
subscription.Data.Exception -= PortfolioService_Exception;
private void PortfolioService_Exception(Exception ex)
{
_logger.LogInformation($"Error: {ex.StackTrace}");
}
例2
如果我这样做,我需要取消订阅-=
吗?
subscription.Data.Exception += (ex) =>
{
_logger.LogInformation($"Error: {ex.StackTrace}");
};
全码
片段
private async Task<bool> InitAsync()
{
var restClient = new BinanceClient(new BinanceClientOptions
{
ApiCredentials = new ApiCredentials(ApiKey, SecretKey),
AutoTimestamp = true,
AutoTimestampRecalculationInterval = TimeSpan.FromMinutes(30),
TradeRulesBehaviour = TradeRulesBehaviour.AutoComply,
#if DEBUG
LogLevel = LogLevel.Debug,
LogWriters = new List<ILogger> { _logger } // TODO: FIX
#endif
});
var socketClient = new BinanceSocketClient(new BinanceSocketClientOptions
{
ApiCredentials = new ApiCredentials(ApiKey, SecretKey),
AutoReconnect = true,
ReconnectInterval = TimeSpan.FromSeconds(15),
#if DEBUG
LogLevel = LogLevel.Debug,
LogWriters = new List<ILogger> { _logger } // TODO: FIX
#endif
});
var listenKeyResult = await restClient.Spot.UserStream.StartUserStreamAsync();
if (!listenKeyResult.Success)
{
return false;
}
var subscription = await socketClient.Spot.SubscribeToUserDataUpdatesAsync(listenKeyResult.Data,
null,
null,
data =>
{
// TODO: Fix the warning
_logger.LogInformation($"ASD {data.Data.Balances}");
},
data =>
{
// TODO: Fix the warning
_logger.LogInformation($"BALANCE DELTA {data.Data.BalanceDelta}");
});
if (!subscription.Success)
{
return false;
}
// Auto unsubscribe?
subscription.Data.Exception += (ex) =>
{
_logger.LogInformation($"Error: {ex.StackTrace}");
};
// Subscribe
subscription.Data.Exception += PortfolioService_Exception;
// Unsubscribe
subscription.Data.Exception -= PortfolioService_Exception;
// TODO: Put a CancellationToken logic and `StopUserStreamAsync`. and subscription.Error -=
var keepAliveTask = Task.Run(async () =>
{
while (true)
{
// Listen key is kept alive for 60 minutes.
await restClient.Spot.UserStream.KeepAliveUserStreamAsync(listenKeyResult.Data);
await Task.Delay(TimeSpan.FromMinutes(50));
}
});
return true;
}
private void PortfolioService_Exception(Exception ex)
{
_logger.LogInformation($"Error: {ex.StackTrace}");
}
图书馆
using CryptoExchange.Net.Objects;
using System;
using System.Threading.Tasks;
namespace CryptoExchange.Net.Sockets
{
/// <summary>
/// Subscription to a data stream
/// </summary>
public class UpdateSubscription
{
private readonly SocketConnection connection;
private readonly SocketSubscription subscription;
/// <summary>
/// Event when the connection is lost. The socket will automatically reconnect when possible.
/// </summary>
public event Action ConnectionLost
{
add => connection.ConnectionLost += value;
remove => connection.ConnectionLost -= value;
}
/// <summary>
/// Event when the connection is closed. This event happens when reconnecting/resubscribing has failed too often based on the <see cref="SocketClientOptions.MaxReconnectTries"/> and <see cref="SocketClientOptions.MaxResubscribeTries"/> options,
/// or <see cref="SocketClientOptions.AutoReconnect"/> is false
/// </summary>
public event Action ConnectionClosed
{
add => connection.ConnectionClosed += value;
remove => connection.ConnectionClosed -= value;
}
/// <summary>
/// Event when the connection is restored. Timespan parameter indicates the time the socket has been offline for before reconnecting.
/// Note that when the executing code is suspended and resumed at a later period (for example laptop going to sleep) the disconnect time will be incorrect as the diconnect
/// will only be detected after resuming. This will lead to an incorrect disconnected timespan.
/// </summary>
public event Action<TimeSpan> ConnectionRestored
{
add => connection.ConnectionRestored += value;
remove => connection.ConnectionRestored -= value;
}
/// <summary>
/// Event when the connection to the server is paused based on a server indication. No operations can be performed while paused
/// </summary>
public event Action ActivityPaused
{
add => connection.ActivityPaused += value;
remove => connection.ActivityPaused -= value;
}
/// <summary>
/// Event when the connection to the server is unpaused after being paused
/// </summary>
public event Action ActivityUnpaused
{
add => connection.ActivityUnpaused += value;
remove => connection.ActivityUnpaused -= value;
}
/// <summary>
/// Event when an exception happens during the handling of the data
/// </summary>
public event Action<Exception> Exception
{
add => subscription.Exception += value;
remove => subscription.Exception -= value;
}
/// <summary>
/// The id of the socket
/// </summary>
public int SocketId => connection.Socket.Id;
/// <summary>
/// The id of the subscription
/// </summary>
public int Id => subscription.Id;
/// <summary>
/// ctor
/// </summary>
/// <param name="connection">The socket connection the subscription is on</param>
/// <param name="subscription">The subscription</param>
public UpdateSubscription(SocketConnection connection, SocketSubscription subscription)
{
this.connection = connection;
this.subscription = subscription;
}
/// <summary>
/// Close the subscription
/// </summary>
/// <returns></returns>
public Task CloseAsync()
{
return connection.CloseAsync(subscription);
}
/// <summary>
/// Close the socket to cause a reconnect
/// </summary>
/// <returns></returns>
internal Task ReconnectAsync()
{
return connection.Socket.CloseAsync();
}
/// <summary>
/// Unsubscribe a subscription
/// </summary>
/// <returns></returns>
internal async Task UnsubscribeAsync()
{
await connection.UnsubscribeAsync(subscription).ConfigureAwait(false);
}
/// <summary>
/// Resubscribe this subscription
/// </summary>
/// <returns></returns>
internal async Task<CallResult<bool>> ResubscribeAsync()
{
return await connection.ResubscribeAsync(subscription).ConfigureAwait(false);
}
}
}
发布于 2021-11-11 22:12:58
示例1和示例2做的事情完全一样。唯一的区别是,在示例1中,您的处理程序有一个名称,而在示例2中,它没有名称(即匿名)。因为它没有名称,所以很难向-=
注销处理程序,因为您似乎已经知道了这一点。
如果希望能够使用lambda,但也希望能够取消订阅,则可以首先将lambda分配给变量。
Action<Exception> tmp = ex => _logger.LogInformation($"Error: {ex.StackTrace}");
subscription.Data.Exception += tmp;
subscription.Data.Exception -= tmp; //Unsubscribe
https://stackoverflow.com/questions/69934367
复制相似问题