Использование неназначенной локальной переменной 'accessor

1

Может кто-нибудь, пожалуйста, помогите мне определить, что здесь не так?

accessor.Dispose();

Вызывает ошибку компилятора, но только в методе Read. Запись компилируется отлично, не прочитав так, что я озадачен...

    public bool Read(ref byte[] bytes)
    {
        MemoryMappedViewAccessor accessor;
        Lock.WaitOne();
        try
        {                
            accessor = Mmf.CreateViewAccessor(0, DataLength);
            bytes = new byte[DataLength];
            accessor.ReadArray<byte>(0, bytes, 0, DataLength);                
        }
        catch
        {
            return false;
        }
        finally
        {
            accessor.Dispose();
            Lock.ReleaseMutex();
        }

        return true;
    }

    public bool Write(byte[] bytes)
    {
        MemoryMappedViewAccessor accessor;
        Lock.WaitOne();
        try
        {
            DataLength = bytes.Length;
            accessor = Mmf.CreateViewAccessor(0, bytes.Length);
            accessor.WriteArray<byte>(0, bytes, 0, bytes.Length);
        }
        catch
        {
            return false;
        }
        finally
        {
            Dispose();
            Lock.ReleaseMutex();
        }
        return true;
    }
  • 0
    Просто примечание: вы вызываете метод Dispose() вашего класса в вашем методе Write вместо accessor.Dispose(); , Это может привести к непреднамеренному поведению.
Теги:
compiler-errors

4 ответа

2

Возможно, исключение должно быть выбрано внутри try и до того, как accessor получит значение. Некоторые способы могут произойти:

  1. Исключение прерывания потока
  2. Исключение из памяти, выделяющее новый объект
  3. Исключение в конструкторе объекта, который вы ему назначаете.

Что касается того, что с этим делать; есть два достаточно простых варианта:

  1. Используйте using этой переменной, чтобы компилятор мог выполнить всю работу за вас.
  2. Инициализируйте accessor к null и удалите его, только если он не равен null.
1

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

Я бы реорганизовал это вместо using блока using:

public bool Read(ref byte[] bytes)
{
    Lock.WaitOne();
    try
    {                
        using (MemoryMappedViewAccessor accessor = Mmf.CreateViewAccessor(0, DataLength))
        {
            bytes = new byte[DataLength];
            accessor.ReadArray<byte>(0, bytes, 0, DataLength);                
            return true;
        }
    }
    catch
    {
        return false;
    }
    finally
    {
        Lock.ReleaseMutex();
    }
}

Альтернативой было бы инициализировать значение null inline, а затем проверить значение null до вызова Dispose, но для этого потребуется больше кода, где в качестве используемого блока упрощает код в целом.

  • 0
    Таким образом, улов в этом примере будет выполнен, даже если исключение происходит в блоке using?
  • 0
    @ user1778306 Да.
1

Вы должны были получить такую же ошибку как в методе Read и Write, но код в методе Write неправильный, поэтому он избегает ошибки.

В Write есть:

    finally
    {
        Dispose();
        Lock.ReleaseMutex();
    }

но это должно было быть:

    finally
    {
        accessor.Dispose();
        Lock.ReleaseMutex();
    }

Ошибка компилятора заключается в том, что в finally блоке может оказаться без значения, назначаемого для accessor. Это произойдет, если вы получите исключение при создании объекта, который вы назначаете varialble.

Чтобы исправить ошибку компилятора, вы можете установить null значение переменной accessor перед блоком try:

MemoryMappedViewAccessor accessor = null;

Затем в блоке finally вы проверяете, есть ли у вас фактический объект для утилизации:

    finally
    {
        if (accessor != null) {
            accessor.Dispose();
        }
        Lock.ReleaseMutex();
    }
0

e только декалирует переменную MemoryMappedViewAccessor accessor; И затем пытаюсь использовать его в блоке Read. Таким образом, вы получаете компилятор error.u

Но в записи вы просто вызываете dispose (не accessor.Dispose()), поэтому нет ошибки. Может быть ошибка ввода?

Вам необходимо инициализировать аксессуар, прежде чем окончательно заблокировать. Может потребоваться исправить, наконец, запись.

Читать:

finally
        {
            accessor.Dispose();
            Lock.ReleaseMutex();
        }

Написать:

 finally
        {
            Dispose();
            Lock.ReleaseMutex();
        }

Ещё вопросы

Сообщество Overcoder
Наверх
Меню