How to use an AppDomain to limit a static class' scope for thread-safe use?

后端 未结 6 2034
我在风中等你
我在风中等你 2021-01-05 10:31

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

I have several shared classes and members in the solution, and during development all

相关标签:
6条回答
  • 2021-01-05 10:50

    Creating and tearing down an appdomain for each call - I take it you're not worried about performance on this one?

    Ideally you should change the called code to be threadsafe.

    0 讨论(0)
  • 2021-01-05 10:55

    Which bit, exactly, is being a pain in terms of thread safety? I can't see any static state nor singletons - and there seems to be appropriate "new" objects... am I being blind?

    So what is the symptom you are seeing...

    An AppDomain answer will be (relatively) slow. As part of a middleware-backed system this might be OK (i.e. the "relatively" is in the same ball-park).

    If you do have some static state somewhere, another option that sometimes works is [ThreadStatic] - which the runtime interprets as "this static field is unique per thread". You need to be careful with initialization, though - the static constructor on thread A might assign a field, but then thread B would see a null/0/etc.

    0 讨论(0)
  • 2021-01-05 10:58

    Why not just put a lock around the code you want to execute sequentially? It will be a bottleneck, but it should work in a multithreaded environment.

    public class Loader
    {
        private static object SyncRoot = new object();
        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()
        {
    
            lock(SyncRoot) {
                dataFile = new DataFile(aredStream, fileName, connectionString);
                dataFile.ParseFile();
               dataFile.Save();
            }
    
        }
    
    }
    
    0 讨论(0)
  • 2021-01-05 11:00

    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.

    0 讨论(0)
  • 2021-01-05 11:06

    If you have shared statics that are conflicting with each other, then you might want to try adding [ThreadStatic] attribute to them. This will make them local to each thread. That may solve your problem in the short term. A correct solution would be to simply rearchitect your stuff to be thread-safe.

    0 讨论(0)
  • 2021-01-05 11:07

    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);       
        }
    }
    
    0 讨论(0)
提交回复
热议问题