Это старый, но самый быстрый и изящный способ, который я смог найти для этого:
def r_delim(s, e)
(a = e%1000) > 0 ? r_delim(s, e/1000) : return; s << a
end
r_delim([], 1234567).join(',')
Я постараюсь добавить тесты в какой-то момент.
Вы не должны использовать ] используя конструкцию
, а лучше избавляйтесь от ваших объектов, когда они больше не нужны:
// сохраняйте список сильных ссылок, чтобы избежать сборки мусора,
// и избавляемся от них всех, если мы избавляемся от инкапсулирующего объекта
закрытый список только для чтения _activeClients = новый список ();
private void Preload (слайд SlideHandler)
{
Клиент PreloadClient = новый PreloadClient ();
_activeClients.Add (клиент);
client.PreloadCompleted + = client_PreloadCompleted;
client.Preload (слайд);
}
private void client_PreloadCompleted (отправитель объекта,
SlidePreloadCompletedEventArgs e)
{
Клиент PreloadClient = отправитель как PreloadClient;
// делаем что-нибудь
client.PreloadCompleted - = client_PreloadCompleted;
client.Dispose ();
_activeClients.Remove (клиент);
}
в этом случае вы должны удалить всех клиентов при удалении основного класса:
защищенное переопределение Dispose (bool dispose)
{
foreach (клиент PreloadClient в _activeClients)
{
client.PreloadCompleted - = client_PreloadCompleted;
client.Dispose ();
}
_activeClients.Clear ();
base.Dispose (утилизация);
}
Обратите внимание, что эта реализация не является потокобезопасной.
_activeClients
должен быть поточно-ориентированным , поскольку ваш PreloadCompleted
метод вызывается из другого потока. try
/ finally
внутри обработчика событий, чтобы гарантировать, что объект будет удален во всех случаях Ну, удаление object используется для уничтожения ресурсов, которые вы не хотите удерживать, пока GC (в конечном итоге) не придет и не заберет ваш объект. Убивает ли ваш метод dispose все, что вам нужно в client_PreloadCompleted
?
Вы можете настроить удаление объекта, когда все ожидаемые обратные вызовы выполнены: Сохраните «счетчик ссылок» для каждого ожидаемого обратного вызова и уменьшайте его при каждом обратном вызове - проверьте наличие null в конце обработчика обратного вызова и удалите, если это так.
Другое обходное решение: не беспокойтесь о IDisposable
. GC заберет ваш объект. Вероятно, вы не хотите, чтобы обработчик обратного вызова (который может не запускаться) имел критическое состояние. Он (обратный вызов) должен просто открывать любые ресурсы, которые ему нужны при вызове, а затем закрывать их.
Если есть зарегистрированные обработчики событий, вы не можете действительно удалить объект, пока есть события, которые могут быть вызваны для него. Лучше всего сделать содержащий класс одноразовым и сохранить клиента в переменной класса, который будет удален, когда содержащий класс.
Что-то вроде
class ContainingClass : IDisposable
{
private PreloadClient m_Client;
private void Preload(SlideHandler slide)
{
m_Client = new PreloadClient())
m_Client.PreloadCompleted += client_PreloadCompleted;
m_Client.Preload(slide);
}
private void client_PreloadCompleted(object sender, SlidePreloadCompletedEventArgs e)
{
}
public void Dispose()
{
if (m_Client != null)
m_Client.Dispose();
}
}
У меня есть несколько идей:
Асинхронное ожидание и детерминированное удаление не очень хорошо сочетаются. Если вы можете найти способ разбить код таким образом, чтобы одноразовые материалы относились к одному классу, а события - к другому, это упростило бы все.
Почему бы не удалить в методе client_PreloadCompleted
?
Подобно тому, что предлагал thecoop, только с помощью вызова Dispose
внутри вышеуказанного метода после того, как вы получили доступ ко всем необходимым данным изнутри клиентского объекта.
Изменить: я думаю, что это то, что предлагал orialmog. .