В конце блока (bookmark1), в вашем примере, будет удален только объект 1. В случае файлового потока это означает, что поток будет закрыт и дескриптор будет освобожден, но фактический строковый объект все еще будет в памяти (готов к очистке GC). В вашем случае Object2 не будет утилизирован, поэтому используемый им дескриптор будет по-прежнему оставаться открытым. В конце концов, GC соберет его и вызовет его финализатор, после чего он будет выпущен правильно.
Если вы хотите, чтобы оба объекта были "очищены" правильно, их нужно будет удалить либо с помощью переноса их в инструкции, либо с помощью вызова Dispose вручную.
Существует также альтернативный, потенциально более чистый синтаксис:
using (Object1 obj1 = new Object1(), Object2 obj2 = new Object2())
{
// Do something with obj1 & obj2
}
Если вы сделаете это, оба obj1 и obj2 будут расположены в конце блока. В вашем случае это означает, что оба объекта будут закрыты, а их дескрипторы отпущены. Затем сборщик мусора очистит их при следующей сборке мусора.
Подробнее см. Страница MSDN по использованию.