我经常从另一个进程正在写入的内存映射文件中读取并使用互斥锁来同步此操作.到目前为止,在我的几个测试中,这个工作正常,但是...如果我的应用程序在获取互斥锁之后和释放之前崩溃了怎么办?有没有办法保证互斥锁的发布,即使发生了这样的崩溃?
另外,我如何处理其他进程的崩溃,这可能还没有释放互斥锁呢?每次调用mutex.WaitOne()时,是否需要处理AbandonedMutexException?
现在我正在这样做:
public MyState GetState()
{
MyState state = new State();
this._mutex.WaitOne();
try
{
state.X = this._mmView.ReadSingle(0);
state.Y = this._mmView.ReadSingle(4);
[..]
}
finally
{
this._mutex.ReleaseMutex();
}
return state;
}
Run Code Online (Sandbox Code Playgroud)
_mmView是我之前实例化的MemoryMappedViewAccessor.整个方法GetState()作为游戏循环的一部分被调用每个帧,因此大约每隔几毫秒.
PS:此外,还有其他明显的问题,为什么这可能会失败,我还没有提到?
我无法理解Vista和/或Windows 7中注册表操作的VirtualStore虚拟化.我认为在以标准用户身份运行时尝试将某些内容写入HKEY_LOCAL_MACHINE根目录会提示Windows虚拟化操作并写入HKEY_CURRENT_USER/Classes/VirtualStore /而是机器.我已经看到几个较旧的应用程序的行为完全相同.
但是,当尝试在C#和.Net4中复制该行为时,对HKLM的写入操作失败,而是使用UnauthorizedAccessException.有没有办法强制虚拟化?
为这个问题提供一些上下文:我正在尝试阅读和操作最初由另一个遗留应用程序创建的注册表项.在Vista或Windows 7中,这些将位于VirtualStore中.我想为WinXP及以上版本使用相同的注册表访问逻辑,并认为我的注册表操作将与旧版应用程序中的操作一样虚拟化(并且会因为相同的键而操作).这不能按预期工作,我知道的唯一解决方法是专门访问VirtualStore路径,如果用户运行Vista或7并启用了UAC ......但是,看起来很难看,特别是如果微软决定更改虚拟化行为未来的Windows版本.
我正在尝试使用LuaInterface 2.0.3在我的C#应用程序中嵌入一些Lua脚本功能.到目前为止,这工作正常,但我无法弄清楚如何限制只访问少数指定的.Net类.默认情况下,所有.Net库都可以通过"luanet"直接访问,Lua脚本可以自由打开新窗口或访问文件系统.
例如,这个Lua脚本将打开一个新窗口:
Form = luanet.System.Windows.Forms.Form
mainForm = Form()
mainForm:ShowDialog()
Run Code Online (Sandbox Code Playgroud)
编写脚本的自由很棒,但这可能会干扰托管应用程序,并且具有一些我不太喜欢的与安全相关的含义.有没有办法禁用它?
我目前正在尝试使用MVVM模式创建一个小应用程序.但是我真的不知道如何在我的ViewModel中正确包装聚合的Model类.从我对MVVM的了解不多,您不应该将ViewModel中的Models公开为属性,否则您可以直接从View中绑定到Model.所以我似乎必须将嵌套模型包装在另一个ViewModel中,但是这会在稍后同步Model和ViewModel时带来一些问题.
那么你如何有效地做到这一点?
我举一个简短的例子.假设我有以下模型类:
public class Bar
{
public string Name { get; set; }
}
public class Foo
{
public Bar NestedBar { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
现在我相应地创建了两个ViewModel类,包装了Models,但遇到了FooViewModel的问题:
public class BarViewModel
{
private Bar _bar;
public string Name
{
get { return _bar.Name; }
set { _bar.Name = value; }
}
}
public class FooViewModel
{
private Foo _foo;
public BarViewModel Bar
{
get { return ???; }
set { ??? = value; }
}
}
Run Code Online (Sandbox Code Playgroud)
现在我如何处理FooViewModel的Bar属性?为了"get"工作,我需要返回一个BarViewModel实例.我是否在FooViewModel中创建了该类型的新字段,并将_foo.NestedBar对象包装在那里?对该字段属性的更改应向下传播到基础Bar实例,对吧?
如果我需要将另一个BarViewModel实例分配给该属性,如下所示:
foo.Bar = …Run Code Online (Sandbox Code Playgroud) 我在构造函数中实例化一个一次性对象(在我的例子中是一个FileStream),需要对它进行一些工作.但是,这可能会引发任何数量的不同异常.现在我甚至不想过多地处理这些异常,并希望允许它们传播给调用者.但是,我需要先处理对象.现在最好的方法是什么?现在我只能想到这样的事情:
IDisposable disposableObject = InstantiateDisposable();
bool error = false;
try
{
DoWork(disposableObject);
}
catch (ReallyBadException e)
{
error = true;
throw new EvenWorseException("some message", e);
}
catch (Exception)
{
error = true;
throw;
}
finally
{
if (error) disposableObject.Dispose();
}
Run Code Online (Sandbox Code Playgroud)
这是否正确或在某些特殊情况下是否会跳过Dispose()?有更简单的方法吗?它有点麻烦,如果你因为某种原因需要分别捕获一堆不同的异常,你总是需要复制并粘贴那个error = true;位.
编辑:
只是为了澄清:我只需要在DoWork()失败/抛出异常时处置该对象.如果这个方法成功,我不想暂时处理这个对象,因为稍后会有更多的工作要做.