Может кто-нибудь, пожалуйста, помогите мне определить, что здесь не так?
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;
}
Возможно, исключение должно быть выбрано внутри try
и до того, как accessor
получит значение. Некоторые способы могут произойти:
Что касается того, что с этим делать; есть два достаточно простых варианта:
using
этой переменной, чтобы компилятор мог выполнить всю работу за вас.accessor
к null
и удалите его, только если он не равен null.Проблема в том, что вы используете переменную, но это возможно для того, чтобы ее не удалось инициализировать, если возникло исключение.
Я бы реорганизовал это вместо 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
, но для этого потребуется больше кода, где в качестве используемого блока упрощает код в целом.
Вы должны были получить такую же ошибку как в методе 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();
}
e только декалирует переменную MemoryMappedViewAccessor accessor;
И затем пытаюсь использовать его в блоке Read. Таким образом, вы получаете компилятор error.u
Но в записи вы просто вызываете dispose (не accessor.Dispose()), поэтому нет ошибки. Может быть ошибка ввода?
Вам необходимо инициализировать аксессуар, прежде чем окончательно заблокировать. Может потребоваться исправить, наконец, запись.
Читать:
finally
{
accessor.Dispose();
Lock.ReleaseMutex();
}
Написать:
finally
{
Dispose();
Lock.ReleaseMutex();
}
Dispose()
вашего класса в вашем методеWrite
вместоaccessor.Dispose();
, Это может привести к непреднамеренному поведению.