2015-07-09 4 views
0

Я работаю над проектом, в котором отдельные области карты генерируются динамически или загружаются из файла, если они уже созданы и сохранены. Регионы загружаются/генерируются только по мере необходимости и сохраняются и отбрасываются, когда их больше нет. Существует несколько различных задач, которые будут использовать одну или несколько областей этой карты для различных целей. Например, одна из этих задач будет заключаться в том, чтобы нарисовать все видимые в настоящее время области (около 9 в любой момент времени). Другим является получение информации или даже изменение регионов. Проблема в том, что эти задачи могут работать или не работать с теми же областями, что и другие задачи.Управление пулом генерируемых объектов

Поскольку эти регионы довольно велики и являются дорогостоящими для создания, было бы проблематично (по этим и другим причинам) использовать разные копии для каждой задачи. Скорее, я думаю, было бы неплохо создать и управлять пулом загруженных в настоящее время регионов. Новые задачи сначала будут проверять пул для их региона. Затем они могут использовать его, если он существует, или создать новый, и добавить его в пул.

При условии, что это работает, как мне управлять этим бассейном? Как я могу определить, что регион больше не нужен никакими задачами и может быть безопасно отброшен? Неужели я глуп и это изнуряюще?

Я использую C#, если это важно для всех.

Редактировать: Теперь, когда я бодрствую, было бы так же просто, как увеличивать счетчик в каждом регионе для каждого используемого им места? затем отбрасывая его, когда счетчик достигает 0?

+0

Являются ли объекты региона неизменяемыми после создания? –

+0

К сожалению нет. Определенная задача будет изменять регионы. В этом случае я, вероятно, подниму флаг «update» в объекте region, а затем обновить все остальные задачи, используя его. – Camander

ответ

1

При условии, что это работает, как мне управлять этим бассейном? Как я могу определить, что регион больше не нужен никакими задачами и может быть безопасно отброшен?

Простой способ сделать это может быть использование слабых ссылок:

public class RegionStore 
{ 
    // I'm using int as the identifier for a region. 
    // Obviously this must be some type that can serve as 
    // an ID according to your application's logic. 
    private Dictionary<int, WeakReference<Region>> _store = new Dictionary<int, WeakReference<Region>>(); 
    private const int TrimThreshold = 1000; // Profile to find good value here. 
    private int _addCount = 0; 
    public bool TryGetRegion(int id, out Region region) 
    { 
    WeakReference<Region> wr; 
    if(!_store.TryGetValue(id, out wr)) 
     return false; 
    if(wr.TryGetTarget(out region)) 
     return true; 
    // Clean up space in dictionary. 
    _store.Remove(id); 
    return false; 
    } 
    public void AddRegion(int id, Region region) 
    { 
    if(++_addCount >= TrimThreshold) 
     Trim(); 
    _store[id] = new WeakReference<Region>(region); 
    } 
    public void Remove(int id) 
    { 
    _store.Remove(id); 
    } 
    private void Trim() 
    { 
    // Remove dead keys. 
    // Profile to test if this is really necessary. 
    // If you were fully implementing this, rather than delegating to Dictionary, 
    // you'd likely see if this helped prior to an internal resize. 
    _addCount = 0; 
    var keys = _store.Keys.ToList(); 
    Region region; 
    foreach(int key in keys) 
     if(!_store[key].TryGetTarget(out wr)) 
     _store.Remove(key); 
    } 
} 

Теперь у Вас есть запас ваших Region объектов, но магазин не мешает им быть мусора, если нет существуют другие ссылки на них.

Определенная задача будет изменять регионы. В этом случае я, вероятно, подниму флаг «update» в объекте region, а затем обновить все остальные задачи, используя его.

Обратите внимание, что это будет определенный потенциальный источник ошибок в приложении в целом. Mutability усложняет любое кэширование. Если вы можете перейти к неизменяемой модели, это, скорее всего, упростит ситуацию, но тогда использование устаревших объектов приносит свои собственные осложнения.

+0

Спасибо, я не знал о слабых ссылках, но они, безусловно, выглядят многообещающими.К сожалению, я не могу придумать разумный способ использования неизменяемой модели, как вы предложили. Не могли бы вы уточнить, с какими проблемами я столкнулся? – Camander

+0

Получив немного ближе, кажется, что слабые ссылки на самом деле не сработают. Объекты должны быть сохранены до gc'd, поэтому мне все равно придется обрабатывать его вручную. – Camander

+0

В финальных играх можно сделать некоторые странные вещи, но это, вероятно, очень плохая идея. –

-1

нормально, я не знаю, как вы ваше приложение разработан, но я sugest вам взглянуть на this

Вы также можете использовать статические для обмена вам переменную с другими задачами, но тогда вы можете используйте блокирующие переменные, чтобы вы не могли писать или читать эту переменную, в то время как другие процессы используют ее. (here)

Смежные вопросы