c# – 如何使用AppDomain限制静态类的范围以便线程安全使用?

前端之家收集整理的这篇文章主要介绍了c# – 如何使用AppDomain限制静态类的范围以便线程安全使用?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我被一个架构不佳的解决方案所困扰.它不是线程安全的!

我在解决方案中有几个共享类和成员,在开发期间一切都很酷……
BizTalk已经沉没了我的战舰.

我们使用自定义BizTalk适配器来调用我的程序集.适配器正在调用我的代码并并行运行,所以我假设它在同一个AppDomain下使用多个线程.

我想要做的是让我的代码在自己的AppDomain下运行,这样我所拥有的共享问题就不会相互混淆.

我有一个非常简单的类,BizTalk适配器实例化然后运行Process()方法.

我想在我的Process()方法中创建一个新的AppDomain,所以每次BizTalk都旋转另一个线程时,它将拥有自己的静态类和方法版本.

BizTalkAdapter代码

  1. // this is inside the BizTalkAdapter and it is calling the Loader class //
  2. private void SendMessage(IBaseMessage message,TransactionalTransmitProperties properties)
  3. {
  4.  
  5. Stream strm = message.BodyPart.GetOriginalDataStream();
  6. string connectionString = properties.ConnectionString;
  7. string msgFileName = message.Context.Read("ReceivedFileName","http://schemas.microsoft.com/BizTalk/2003/file-properties") as string;
  8.  
  9.  
  10. Loader loader = new Loader(strm,msgFileName,connectionString);
  11. loader.Process();
  12.  
  13. EventLog.WriteEntry("Loader","Successfully processed: " + msgFileName);
  14.  
  15. }

这是BizTalk调用类:

  1. public class Loader
  2. {
  3.  
  4. private string connectionString;
  5. private string fileName;
  6. private Stream stream;
  7. private DataFile dataFile;
  8.  
  9. public Loader(Stream stream,string fileName,string connectionString)
  10. {
  11. this.connectionString = connectionString;
  12. this.fileName = fileName;
  13. this.stream = stream;
  14. }
  15.  
  16. public void Process()
  17. {
  18.  
  19. //***** Create AppDomain HERE *****
  20. // run following code entirely under that domain
  21. dataFile = new DataFile(aredStream,fileName,connectionString);
  22. dataFile.ParseFile();
  23. dataFile.Save();
  24. // get rid of the AppDomain here...
  25.  
  26. }
  27.  
  28. }

仅供参考:Loader类位于dataFile类的单独DLL中.

任何帮助,将不胜感激.我将继续努力使代码线程安全,但我觉得这可能是“简单”的答案.

如果有人有任何其他想法,请投入.

谢谢,
基思

Just for completeness.

I did find that if I marked the send adapter as “Ordered Delivery” in
the “Transport Advanced Options” dialog I was able to avoid the
multi-thread issues I was having.

I figure this is another possible answer to my problem,but not
necessarily to the question.

解决方法

使用应用域您可以执行以下操作:
  1. public class Loader
  2. {
  3.  
  4. private string connectionString;
  5. private string fileName;
  6. private Stream stream;
  7. private DataFile dataFile;
  8.  
  9. public Loader(Stream stream,string connectionString)
  10. {
  11. this.connectionString = connectionString;
  12. this.fileName = fileName;
  13. this.stream = stream;
  14. }
  15.  
  16. public void Process()
  17. {
  18. //***** Create AppDomain HERE *****
  19. string threadID = Thread.CurrentThread.ManagedThreadId.ToString();
  20. AppDomain appDomain = AppDomain.CreateDomain(threadID);
  21.  
  22. DataFile dataFile =
  23. (DataFile) appDomain.CreateInstanceAndUnwrap(
  24. "<DataFile AssemblyName>","DataFile",true,BindingFlags.Default,null,new object[]
  25. {
  26. aredstream,filename,connectionString
  27. },null);
  28. dataFile.ParseFile();
  29. dataFile.Save();
  30.  
  31. appDomain.Unload(threadID);
  32. }
  33. }

猜你在找的C#相关文章