如何使用 AppDomain 来限制线程安全使用的静态类的范围? [英] How to use an AppDomain to limit a static class' scope for thread-safe use?

查看:21
本文介绍了如何使用 AppDomain 来限制线程安全使用的静态类的范围?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我被一个糟糕的架构解决方案所困扰.它不是线程安全的!

I have been bitten by a poorly architected solution. It is not thread safe!

我在解决方案中有几个共享类和成员,在开发过程中一切都很酷...
BizTalk 击沉了我的战舰.

I have several shared classes and members in the solution, and during development all was cool...
BizTalk has sunk my battle ship.

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

We are using a custom BizTalk Adapter to call my assemblies. The Adapter is calling my code and running things in parallel, so I assume it is using multiple threads all under the same AppDomain.

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

What I would like to do is make my code run under its own AppDomain so the shared problems I have will not muck with each other.

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

I have a very simple class that the BizTalk adapter is instantiating then running a Process() method.

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

I would like to create a new AppDomain inside my Process() method, so each time BizTalk spins another thread, it will have its own version of the static classes and methods.

BizTalkAdapter 代码:

BizTalkAdapter Code:

  // this is inside the BizTalkAdapter and it is calling the Loader class //
  private void SendMessage(IBaseMessage message, TransactionalTransmitProperties properties)
    {

        Stream strm = message.BodyPart.GetOriginalDataStream();
        string connectionString = properties.ConnectionString;
        string msgFileName = message.Context.Read("ReceivedFileName", "http://schemas.microsoft.com/BizTalk/2003/file-properties") as string;


        Loader loader = new Loader(strm, msgFileName, connectionString);
        loader.Process();

        EventLog.WriteEntry("Loader", "Successfully processed: " + msgFileName);

    }

这是 BizTalk Calls 类:

This is the class BizTalk Calls:

public class Loader
{

    private string connectionString;
    private string fileName;
    private Stream stream;
    private DataFile dataFile;

    public Loader(Stream stream, string fileName, string connectionString)
    {
        this.connectionString = connectionString;
        this.fileName = fileName;
        this.stream = stream;
    }  

    public void Process()
    {

        //*****  Create AppDomain HERE *****
        // run following code entirely under that domain
        dataFile = new DataFile(aredStream, fileName, connectionString);
        dataFile.ParseFile();
        dataFile.Save();
        // get rid of the AppDomain here...

    }

}

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

FYI: The Loader class is in a seperate DLL from the dataFile class.

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

Any help would be appreciated. I will continue to working on making the code Thread-Safe, but I feel like this could be the "simple" answer.

如果有人有任何其他想法,请提出.

If anyone has any other thought, please throw in.

谢谢,
基思

只是为了完整性.

我确实发现如果我将发送适配器标记为Ordered Delivery"传输高级选项"对话框我能够避免我遇到的多线程问题.

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.

推荐答案

使用应用程序域,您可以执行以下操作:

Using app domains you could do something like this:

public class Loader
{

    private string connectionString;
    private string fileName;
    private Stream stream;
    private DataFile dataFile;

    public Loader(Stream stream, string fileName, string connectionString)
    {
        this.connectionString = connectionString;
        this.fileName = fileName;
        this.stream = stream;
    }  

    public void Process()
    {
        //*****  Create AppDomain HERE *****
        string threadID = Thread.CurrentThread.ManagedThreadId.ToString();
        AppDomain appDomain = AppDomain.CreateDomain(threadID);

        DataFile dataFile = 
            (DataFile) appDomain.CreateInstanceAndUnwrap(
                        "<DataFile AssemblyName>", 
                        "DataFile", 
                        true, 
                        BindingFlags.Default,
                        null,
                        new object[] 
                        { 
                            aredstream, 
                            filename, 
                            connectionString 
                        },
                        null,
                        null,
                        null);
        dataFile.ParseFile();
        dataFile.Save();

        appDomain.Unload(threadID);       
    }
}

这篇关于如何使用 AppDomain 来限制线程安全使用的静态类的范围?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆