![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Remoting.Messaging;
using System.Threading;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
CallContext.SetData("p1", new Person1 { Name = "xhan"});
CallContext.SetData("p2", new Person2 { Name = "xhan" });
CallContext.LogicalSetData("name", 36);
Action action = PrintPerson;
action.BeginInvoke(null, null);
PrintPerson();
Console.Read();
}
public static void PrintPerson()
{
Console.WriteLine("logicalData:" + CallContext.LogicalGetData("name"));
Person1 p1 = CallContext.GetData("p1") as Person1;
Person2 p2 = CallContext.GetData("p2") as Person2;
if (p1 != null)
{
Console.WriteLine("thread Id:" + Thread.CurrentThread.ManagedThreadId + " p1.Name:" + p1.Name);
}
else
{
Console.WriteLine("thread Id:" + Thread.CurrentThread.ManagedThreadId + " p1.Name:null");
}
if (p2 != null)
{
Console.WriteLine("thread Id:" + Thread.CurrentThread.ManagedThreadId + " p2.Name:" + p2.Name);
}
else
{
Console.WriteLine("thread Id:" + Thread.CurrentThread.ManagedThreadId + " p2.Name:null");
}
}
}
public class Person1
{
public string Name { get; set; }
}
public class Person2 : ILogicalThreadAffinative
{
public string Name { get; set; }
}
}
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Remoting.Messaging;
using System.Threading;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
CallContext.SetData("p1", new Person1 { Name = "xhan"});
CallContext.SetData("p2", new Person2 { Name = "xhan" });
CallContext.LogicalSetData("name", 36);
Action action = PrintPerson;
action.BeginInvoke(null, null);
PrintPerson();
Console.Read();
}
public static void PrintPerson()
{
Console.WriteLine("logicalData:" + CallContext.LogicalGetData("name"));
Person1 p1 = CallContext.GetData("p1") as Person1;
Person2 p2 = CallContext.GetData("p2") as Person2;
if (p1 != null)
{
Console.WriteLine("thread Id:" + Thread.CurrentThread.ManagedThreadId + " p1.Name:" + p1.Name);
}
else
{
Console.WriteLine("thread Id:" + Thread.CurrentThread.ManagedThreadId + " p1.Name:null");
}
if (p2 != null)
{
Console.WriteLine("thread Id:" + Thread.CurrentThread.ManagedThreadId + " p2.Name:" + p2.Name);
}
else
{
Console.WriteLine("thread Id:" + Thread.CurrentThread.ManagedThreadId + " p2.Name:null");
}
}
}
public class Person1
{
public string Name { get; set; }
}
public class Person2 : ILogicalThreadAffinative
{
public string Name { get; set; }
}
}
CallContext一般来说是绑定到特定线程的一个上下文数据存储,我们可以通过CallContext的静态方法GetData, SetData, and FreeNamedDataSlot,来管理线程内上下文数据。但是有些时候,我们需要将一个线程的上下文传递到另一个线程中。比如异步调用一个方法,或者显示创建新的线程。上面的例子说明了通过SetData方法设置的数据对象是不会自动传播上下文到新的线程中。如果要想传递上下文中的对象到新线程。通过SetData放到数据槽中的对象必须实行ILogicalThreadAffinative这个标记接口.另一个方法是通过LogicalSetData和LogicalGetData来放置上下文数据,这种方式放置的对象都会自动传递到新线程中.
另外asp.net中的HttpContext.Current对象也是基于CallContext实现的,而且asp.net中HttpConext.Current不能自动的跨线程传递。http://www.cnblogs.com/whtydn/archive/2009/07/16/1524580.html
参考:http://www.cnblogs.com/vwxyzh/archive/2009/02/21/1395416.html