在Flash 10中,有些方法要求从用户启动的操作(如按钮单击,键盘上/下键等)触发它们。
是否可以在.NET中实现此行为?例如,如果我们有这个子例程:
void SomeMethod() {
// Here some stuff
}
如何检查方法是否是从鼠标单击事件处理程序中调用的?
如果有人知道我的意思,我们也可以把这些方法想象成“魔兽世界”中受保护的功能。
编辑:看起来这种行为是在Silverlight中实现的 - 我们只能通过鼠标点击或其他用户启动的操作弹出文件对话框(打开,保存),否则将抛出SecurityException。 I我希望实现这个bevaviour,但在我的情况下,它不是文件对话框,而是我们自己的方法。
答案 0 :(得分:2)
为什么不将它作为参数提供?
void SomeMethod(bool userInitiated) {
// Here some stuff
}
鉴于你已经在调用它,有时来自事件处理程序,有时候不是,你已经掌握了这些信息。
编辑:另一种方法是使用一个线程静态字段,在进入事件处理程序时设置,然后在退出时重置(在finally块中)。任何想要测试他们是否“响应用户操作”的代码都可以测试该字段。
如果这还不够好,那么我怀疑答案就是“不”。
编辑:你可以进入调用堆栈(请参阅StackTrace
类),但这相对较慢并且可能由于内联而错过堆栈帧。还有Code Access Security 可能只是为了帮助你 - 但我对此表示怀疑。
答案 1 :(得分:0)
您似乎正在编写某种插件API。您希望提供一种方法来执行用户可能不想要的操作,例如更改剪贴板内容,并且您希望确保插件只能响应用户操作来调用该方法。
我能想到的唯一方法是API需要不断了解它当前是否正在处理用户启动的操作。据推测,程序中会有一些代码调用插件提供的代码,例如
if (plugin.HasHandlerForMouseClick)
plugin.HandleMouseClick();
此时您需要记住这是用户启动的操作。一旦方法返回,那就是用户启动的操作的结束:
if (plugin.HasHandlerForMouseClick)
{
_userInitiated = true;
try
{
plugin.HandleMouseClick();
}
finally
{
_userInitiated = false;
}
}
然后,在您的“不安全”方法中,例如要设置剪贴板的那个,你必须检查这个标志:
public void SetClipboard(object newValue)
{
if (!_userInitiated)
return; // or throw AccessDeniedException?
// set clipboard here
}
正如Jon暗示的那样,该字段应该被声明为线程静态的。这意味着每个线程都有一个单独的字段副本:
[ThreadStatic]
private static bool _userInitiated = false;