0

имеется фрагмент кода

int readen = 1;
int i = 0;
while (readen > 0)
{
    if (msList.Count >= 20)
    {
        Thread.Sleep(200);
        continue;
    }
    else
    {
        msList.Add(new MemoryStream());
        gzsList.Add(i, new GZipStream(msList.Last(), CompressionMode.Compress));
        readen = fsIn.Read(buffer, 0, buffer.Length);
        compressTasks.Add(new Task(() => { (gzsList[i] as GZipStream).Write(buffer, 0, readen); }));
        i++;
        compressTasks.Last().Start();
    }
}

проблема в том что в строке compressTasks.Add(new Task(() => { (gzsList[i] as GZipStream).Write(buffer, 0, readen); }));происходят непонятные вещи: при выполнении условия не происходит засыпание треда, а выполнение переходит на эту строку и соответственно вываливается исключение, причем зависящий от типа коллекции gzslist(для List``System.InvalidOperationException, Dictionary KeyNotFoundException, Hashtable NullReferenceException. Если убрать условие, то все равно вываливаются исключения, но при разной величине коллекции(зависит от запуска(от 20 до 50)

andreycha
  • 25,167
  • 4
  • 46
  • 82
  • А зачем вы Task используете как потоки? Почему не современный async/await? – VladD Mar 31 '16 at 22:11
  • И ещё, непонятно, почему добавление Task'а в коллекцию должно приводить к засыпанию потока. – VladD Mar 31 '16 at 22:13
  • А ещё вы расшарили между Task'ами переменную i, это бомба замедленного действия (подумайте, почему). – VladD Mar 31 '16 at 22:15
  • мне кажется, или буфер там тоже общий? – zRrr Mar 31 '16 at 22:47
  • Не добавление должно приводить К засыпанию потока, а после добавления если в коллекции слишком много элементов( тобишь consumer работает медленее producer) необходимо дождаться появления свободного места в коллекции. И можно подробнее почему плохо шарить int между тасками? Он же передается по значению и по идее не должно быть проблем – Artemiy Borodin Apr 01 '16 at 04:08
  • @ArtemiyBorodin: Не, лямбда захватывает i по ссылке. Так что у вас разделяемая переменная с понятными последствиями. – VladD Apr 01 '16 at 16:41
  • @VladD не знал что лямбда захватывает по ссылке, в будущем пригодится, сейчас же сделал нормальную имплементацию Producer-Consumer, попутно выясним что нельзя сжимать куски 1го файла несколькими GZipStream – Artemiy Borodin Apr 02 '16 at 07:52
  • @ArtemiyBorodin: Возможно, вам пригодится это: http://ru.stackoverflow.com/q/428327/10105 – VladD Apr 02 '16 at 11:31

0 Answers0