将 [ThreadStatic] 属性应用于外部程序集中的方法
Posted
技术标签:
【中文标题】将 [ThreadStatic] 属性应用于外部程序集中的方法【英文标题】:Apply [ThreadStatic] attribute to a method in external assembly 【发布时间】:2013-10-28 15:52:37 【问题描述】:我可以像[ThreadStatic]
一样使用外部程序集的static method
方法吗?
这是我的情况。
assembly class
(我无法访问其源代码)具有这种结构
public class RegistrationManager()
private RegistrationManager()
public static void RegisterConfiguration(int ID)
public static object DoWork()
public static void UnregisterConfiguration(int ID)
注册后,如果不取消注册之前注册的 ID,我就无法使用其他 ID 呼叫 DoWork()
。实际上我想通过多线程同时调用具有不同 ID 的 DoWork()
方法。
如果RegisterConfiguration(int ID)
方法是[ThreadStatic]
,我可以在不同的线程中调用它而不会出现调用问题,对吧?那么,我可以将[ThreadStatic]
属性应用于此方法还是有其他方法可以同时调用两个static
方法而无需等待其他线程注销它?
如果我像下面这样检查它,它应该可以工作。
for(int i=0; i < 10; i++)
new Thread(new ThreadStart(() => Checker(i))).Start();
public string Checker(int i)
public static void RegisterConfiguration(i); // Now i cannot register second time
public static object DoWork(i);
Thread.Sleep(5000); // DoWork() may take a little while to complete before unregistered
public static void UnregisterConfiguration(i);
【问题讨论】:
【参考方案1】:我不知道您可以将[ThreadStatic]
添加到外部程序集中,而无需重新编译源代码。
但是,您可以创建额外的应用程序域来同时执行代码。不像线程那么优雅,但仍然是一种潜在的解决方案。
http://msdn.microsoft.com/en-us/library/ms173139%28v=VS.100%29.aspx
根据您可能绑定的许可证,另一个选项是使用use a tool like Reflector 对外部程序集的源代码进行反向工程并添加[ThreadStatic]
属性。
【讨论】:
谢谢 Erik,我会尝试使用不同的应用程序域。我发现this question
与此相关,但是我在不同的AppDomains中调用静态方法时感到困惑,让我试试。
对您引用的问题的接受答案应该可以解决问题。您首先需要创建一个包装器对象,您可以创建一个实例,并让该包装器对象与静态方法交互。让我知道结果如何。
我尝试使用另一个包装库并调用该函数,它调用了该函数,但由于它返回另一个对象,该对象是外部库中不可序列化类的实例。所以我得到了一个序列化异常。当我们调用appDomain1..CreateInstanceAndUnwrap(...).FactoryMethod()
时,是否有创建一个不可序列化的对象并从包装库中返回它?【参考方案2】:
ThreadStatic 适用于字段,而不是方法,所以这个想法从一开始就注定了。应该可以反汇编 dll,修改源代码并重新组装,但这没有实际意义,因为没有简单的方法可以使另一个组件成为线程安全的。
你可能想写一个像这样的包装类:
class RegistraionWrapper
private static Object _lock = new Object();
public static void DoWork(int ID)
lock (_lock)
RegistrationManager.RegisterConfiguration(ID);
RegistrationManager.DoWork();
RegistrationManager.UnregisterConfiguration(ID);
您可能需要将 Unregister 调用放在 finally 块中。当然,锁使得生成多个线程来完成工作变得毫无意义,但不清楚这个库是否支持这一点。最好的办法是与这个库的作者交谈。
【讨论】:
以上是关于将 [ThreadStatic] 属性应用于外部程序集中的方法的主要内容,如果未能解决你的问题,请参考以下文章
使用带有 async/await 的 ThreadStatic 变量