У меня есть класс коллекции, который содержит много разных типов данных в сжатом формате. Для перечисления всех значений в коллекции есть метод Execute(Query, IDataWriter)
. Вы передаете ему запрос, который определяет, какие данные вам нужны, а затем для каждого фрагмента совпадающих данных он вызывает метод объекта IDataWriter, который вы передаете.
Интерфейс IDataWriter имеет 15 различных методов, по одному для каждого типа данных в коллекции. Теперь мне нужно зафиксировать эти данные в базе данных, и я хочу иметь возможность реализовать IEnumerator<SqlDataRecord>
для фиксации материала в базе данных. Проблема заключается в том, как преобразовать вызов Execute, который сбрасывает тонну данных в объект IDataWriter (push), в метод pull, чтобы можно было использовать MoveNext и Current в IEnumerator.
Я посмотрел на сопрограммы и волокна, но ни один из примеров, которые я обнаружил, не показался бы работающим для существующего метода (в моем случае - Execute), который внутренне ничего не знает о корунтине. Так что мой план в псевдокоде состоит в том, чтобы сделать следующее, используя потоки и ручную синхронизацию.
Метод Execute будет выполняться в отдельном потоке, и я буду вручную ждать и сигнализировать его внутри каждого метода IDataWriter
class EnumeratorAdapterObject : IEnumerator<SqlDataRecord>, IDataWriter
{
public EnumeratorAdapterObject(Store storeObject)
{
workerThread = new Thread(storeObject.Execute(query, this));
}
public bool MoveNext()
{
if (firstTimeCalled)
{
start worker thread
}
else
{
signal resume
}
block for either a call into an Add method or the Execute thread finishes
if (not anything buffered)
return false
else
return true
}
// 14 other methods like this implemented in IDataWriter, each with different types
public void Add_Decimal(IntvlDataHeader header, decimal data)
{
buffer field of current SqlDataRecord = generate record;
signal main thread
wait for resume signal
}
public SqlDataRecord Current
{
get { return buffer field of current SqlDataRecord; }
}
}
Это похоже на хороший подход? Кто-нибудь знает какие-либо примеры или вопросы, которые уже реализуют это?
Или можно было бы воспользоваться любой из новых функций 4.0? Я думал об использовании блокирующей параллельной коллекции с ограничением в 1 вещь, но тогда как бы потребитель (MoveNext IEnumerator) узнал, когда другой поток завершит добавление материала?