English 中文(简体)
C#是否有“校对”类比(对数据成员而言)“校对”属性?
原标题:Does C# have a "ThreadLocal" analog (for data members) to the "ThreadStatic" attribute?

我发现,“ThreadStatic”称谓最近极为有用,但现在我想到的是“Thread local” 类型属性,lets本人有非正常数据成员。

现在我知道,这将产生一些非物质影响,但:

www.un.org/Depts/DGACM/index_spanish.htm 在C#/.net?中,是否已有这样的内容,因为迄今为止,对此的答复没有(对于net <4.0),在那里是否普遍使用?

我可以想出一个合理的方式来执行它,但只要有的话,就只能使用已经存在的东西。

Straw Man,如果已经存在,将执行我所期望的:

class Foo
{
    [ThreadStatic] 
    static Dictionary<Object,int> threadLocalValues = new Dictionary<Object,int>();
    int defaultValue = 0;

    int ThreadLocalMember
    {
         get 
         { 
              int value = defaultValue;
              if( ! threadLocalValues.TryGetValue(this, out value) )
              {
                 threadLocalValues[this] = value;
              }
              return value; 
         }
         set { threadLocalValues[this] = value; }
    }
}

请原谅任何C# 无。 I m a C++ developer, 直到最近才进入C# 和 net 更令人感兴趣的特征

www.un.org/Depts/DGACM/index_spanish.htm Im = 3.0 , 或许为3.5 (项目已经/不久将移至3.5)。

具体使用个案是贴切具体名单(使用想象力[现用当地]特性a:

class NonSingletonSharedThing
{
     [ThreadLocal] List<Callback> callbacks;

     public void ThreadLocalRegisterCallback( Callback somecallback )
     {    
         callbacks.Add(somecallback);    
     }

     public void ThreadLocalDoCallbacks();
     {    
         foreach( var callback in callbacks )  
            callback.invoke();  
     }
}
最佳回答
问题回答

你们应两次思考这个问题。 你基本上是造成记忆泄露。 Every, 深层设计的物体仍为参照对象,并可收集垃圾。 直至表面结束。

考虑:

不要试图使每个成员在物体上变异,而是让每个成员阅读自己的物体。 - 将该物体作为国家发射,或使宇宙开端方法成为read子中“own”成员,并为每一read子树立新的榜样。

Edit (in response to Catskul s remark. Here s an example of encapsulating the struct


public class TheStructWorkerClass
{
  private StructData TheStruct;
  public TheStructWorkerClass(StructData yourStruct)
  {
    this.TheStruct = yourStruct;
  }

  public void ExecuteAsync()
  {
    System.Threading.ThreadPool.QueueUserWorkItem(this.TheWorkerMethod);
  }
  private void TheWorkerMethod(object state)
  {
     // your processing logic here
     // you can access your structure as this.TheStruct;
     // only this thread has access to the struct (as long as you don t pass the struct
     // to another worker class)
  }
}

// now hte code that launches the async process does this:
  var worker = new TheStructWorkerClass(yourStruct);
  worker.ExecuteAsync();

现在,选择2(绕过国家结构)


 {
 // (from somewhere in your existing code
    System.Threading.Threadpool.QueueUserWorkItem(this.TheWorker, myStruct);
 } 

  private void TheWorker(object state)
  { 
    StructData yourStruct = (StructData)state;
    // now do stuff with your struct
    // works fine as long as you never pass the same instance of your struct to 2 different threads.
  }

我最后说,我已经执行并测试了我原先建议的文本:

public class ThreadLocal<T>
{
    [ThreadStatic] private static Dictionary<object, T> _lookupTable;

    private Dictionary<object, T> LookupTable
    {
        get
        {
            if ( _lookupTable == null)
                _lookupTable = new Dictionary<object, T>();

            return _lookupTable;
        }
    }


    private object key = new object(); //lazy hash key creation handles replacement
    private T originalValue;

    public ThreadLocal( T value )
    {
        originalValue = value;
    }

    ~ThreadLocal()
    {
        LookupTable.Remove(key);
    }

    public void Set( T value)
    {
        LookupTable[key] = value;
    }

    public T Get()
    {
        T returnValue = default(T);
        if (!LookupTable.TryGetValue(key, out returnValue))
            Set(originalValue);

        return returnValue;
    }
}

虽然我仍然无法确定你使用案件何时有意义(见我对问题本身的评论),但我想提出一个工作例子,我认为,这个例子比对地储存(不论是静态还是例)更可读。 例子正在使用。 NET 3.5:

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Linq;

namespace SimulatedThreadLocal
{
    public sealed class Notifier
    {
        public void Register(Func<string> callback)
        {
            var id = Thread.CurrentThread.ManagedThreadId;
            lock (this._callbacks)
            {
                List<Func<string>> list;
                if (!this._callbacks.TryGetValue(id, out list))
                {
                    this._callbacks[id] = list = new List<Func<string>>();
                }
                list.Add(callback);
            }
        }

        public void Execute()
        {
            var id = Thread.CurrentThread.ManagedThreadId;
            IEnumerable<Func<string>> threadCallbacks;
            string status;
            lock (this._callbacks)
            {
                status = string.Format("Notifier has callbacks from {0} threads, total {1} callbacks{2}Executing on thread {3}",
                    this._callbacks.Count,
                    this._callbacks.SelectMany(d => d.Value).Count(),
                    Environment.NewLine,
                    Thread.CurrentThread.ManagedThreadId);
                threadCallbacks = this._callbacks[id]; // we can use the original collection, as only this thread can add to it and we re not going to be adding right now
            }

            var b = new StringBuilder();
            foreach (var callback in threadCallbacks)
            {
                b.AppendLine(callback());
            }

            Console.ForegroundColor = ConsoleColor.DarkYellow;
            Console.WriteLine(status);
            Console.ForegroundColor = ConsoleColor.Green;
            Console.WriteLine(b.ToString());
        }

        private readonly Dictionary<int, List<Func<string>>> _callbacks = new Dictionary<int, List<Func<string>>>();
    }

    public static class Program
    {
        public static void Main(string[] args)
        {
            try
            {
                var notifier = new Notifier();
                var syncMainThread = new ManualResetEvent(false);
                var syncWorkerThread = new ManualResetEvent(false);

                ThreadPool.QueueUserWorkItem(delegate // will create closure to see notifier and sync* events
                {
                    notifier.Register(() => string.Format("Worker thread callback A (thread ID = {0})", Thread.CurrentThread.ManagedThreadId));
                    syncMainThread.Set();
                    syncWorkerThread.WaitOne(); // wait for main thread to execute notifications in its context

                    syncWorkerThread.Reset();
                    notifier.Execute();
                    notifier.Register(() => string.Format("Worker thread callback B (thread ID = {0})", Thread.CurrentThread.ManagedThreadId));
                    syncMainThread.Set();
                    syncWorkerThread.WaitOne(); // wait for main thread to execute notifications in its context

                    syncWorkerThread.Reset();
                    notifier.Execute();
                    syncMainThread.Set();
                });

                notifier.Register(() => string.Format("Main thread callback A (thread ID = {0})", Thread.CurrentThread.ManagedThreadId));
                syncMainThread.WaitOne(); // wait for worker thread to add its notification

                syncMainThread.Reset();
                notifier.Execute();
                syncWorkerThread.Set();
                syncMainThread.WaitOne(); // wait for worker thread to execute notifications in its context

                syncMainThread.Reset();
                notifier.Register(() => string.Format("Main thread callback B (thread ID = {0})", Thread.CurrentThread.ManagedThreadId));
                notifier.Execute();
                syncWorkerThread.Set();
                syncMainThread.WaitOne(); // wait for worker thread to execute notifications in its context

                syncMainThread.Reset();
            }
            finally
            {
                Console.ResetColor();
            }
        }
    }
}

When you compile and run the above program, you should get output like this: alt text http://img695.imageshack.us/img695/991/threadlocal.png

根据你的使用情况,我假定这是你再次试图实现的目标。 例子首先增加了两个不同背景的反馈:主线和工人线。 然后,首先从主线发出通知,然后从工人线上发出通知。 正在执行的警示实际上由现成的ID过滤。 仅按预期显示工作情况,这个例子又增加了两个反馈(总共为4个),并再次从主线和工人线上发出通知。

请注意,诺琴蒂语系是一种可以立州、多处例(根据你的问题使用情况)的普通类。 例如,没有静态或静态或深层的地方。

如果你能看一下该守则,请让我知道,我是否误解了你为达到的目标而重新做些什么,或者这种技术符合你们的需要。

我不敢肯定,你如何首先检查你的胎面,但是,有办法让每个胎面的 storage子储存起来,而不像你在你的提问中所贴出的法典那样,使用黑板的工作。

public void SpawnSomeThreads(int threads)
{
    for (int i = 0; i < threads; i++)
    {
        Thread t = new Thread(WorkerThread);

        WorkerThreadContext context = new WorkerThreadContext
        {
            // whatever data the thread needs passed into it
        };

        t.Start(context);
    }
}

private class WorkerThreadContext
{
    public string Data { get; set; }
    public int OtherData { get; set; }
}

private void WorkerThread(object parameter)
{
    WorkerThreadContext context = (WorkerThreadContext) parameter;

    // do work here
}

这显然忽视了等待完成工作的准备,确保获得任何共同国家的机会在全体工人的read子中都变得暗淡,但你却有了想法。

尽管所张贴的解决方案看起来有弊端,但它却泄露了物体。 定稿者——可检索。 Remove (key) - isî only in the context of the GC thread so will only establishing more garbage in establishing another lookup table.

你们需要从每个已经到达当地人的透视桌上删除物体。 我认为解决这一问题的唯一合法途径是,关键词典薄弱,这种数据结构奇怪地缺乏。





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签