Home All Groups Group Topic Archive Search About

Threads and CallContext problems

Author
15 Aug 2006 12:00 PM
Troy
Hi

When upgrading from .net framework v1.1 to v2.0 i ran into a little problem
regarding the CallContext method. I have enclosed an example that illustrates
my problem.

When compiling in v1.1 it works fine, the Test.exe will print out
"ContextTest = Hello world!" as expected. Doing the same compiled under v2.0
it returns "ContextTest = NULL" ???

The test example is a simplified version of the application we are
upgrading, so the CallContext must be used since the remoting is heavily
depended on it.

We are using a Form to switch context into the other thread through Invoke,
i am not sure if this is recommended but i don’t know of any other way to do
it?!

Hope you can help me here, Thanks in advance -  Cheers :)

(Ignore the Form poping up, only the console output i relevant)

>>>> Compile batch file
@echo off
cls
setlocal
REM set CSC_PATH=c:\WINDOWS\Microsoft.NET\Framework\v1.1.4322
set CSC_PATH=C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727

%CSC_PATH%\csc /out:Test.exe /target:exe Test.cs
<<<<<


>>>>> Test.cs file

using System;
using System.Runtime.Remoting.Messaging;
using System.Threading;
using System.Windows.Forms;

namespace Test
{
    public interface IClient {
      void Start();
      void ContextTest();
    }

    public class ContextData : ILogicalThreadAffinative
    {
        public static readonly string CONTEXT_NAME =
typeof(ContextData).ToString();
        private string text;

        public string Text
        {
            get { return text; }
            set { text = value; }
        }

        public ContextData( string text )
        {
            Text = text;
        }

        public override string ToString()
        {
            return Text;
        }
    }

    public class Client : IClient
    {
        private Thread thread = null;
        private ManualResetEvent initEvent;
        private Form contextSwitch;

        public Client()
        {
            initEvent = new ManualResetEvent(false);
        }

        public void Start()
        {
            thread = new Thread(new ThreadStart(Run));
            thread.Name = "Client";
            thread.Start();

            initEvent.WaitOne();
        }

        private void Run()
        {
            // Do init stuff
            contextSwitch = new Form();
            contextSwitch.Visible = false;
            if (contextSwitch.IsHandleCreated == false)
            {
                // Provoke handle creation...
                IntPtr dummy = contextSwitch.Handle;
            }
            CallContext.SetData(ContextData.CONTEXT_NAME, new
ContextData("Hello world!"));
            initEvent.Set();

            // Do loop stuff
            // We will never get back from here...
            Application.Run(contextSwitch);
        }

        delegate void VoidDelegate();

        public void ContextTest()
        {
            if ( contextSwitch.InvokeRequired == true)
            {
                contextSwitch.Invoke(new VoidDelegate(ContextTest));
                return;
            }
            Object obj = CallContext.GetData(ContextData.CONTEXT_NAME);
            Console.WriteLine("ContextTest = " + (obj == null ? "NULL" :
obj.ToString()));
        }

    }

    class Test
    {
        [MTAThread]
        static void Main(string[] args)
        {
            Thread.CurrentThread.Name = "Main";
            IClient client = new Client();

            client.Start();
            client.ContextTest();
        }
    }
}

<<<<

AddThis Social Bookmark Button