Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

COM library Initialization failed with code 0x80010106 in C#

Tags:

c#

I was trying to push data manually to NT using c# but i was getting an error as: "Failed to initialize COM library(0x80010106)." I have already added the reference 'Ninjatrader.Client.dll' I am posting my code as below:

using System;
using System.Runtime.InteropServices;
using System.Threading; 
using System.Diagnostics;

namespace read_file
{
 public static class Program
 {
    [DllImport("NtDirect.dll", EntryPoint = "Connected", SetLastError = true)]
    public extern static int Connected(int showMessage);

    [DllImport("NtDirect.dll", SetLastError = true)]
    public static extern int Last(string instrument, double price, int size);

    public static void Main(string[] args)
    {
        NinjaTrader.Client.Client NTClient = new NinjaTrader.Client.Client();
        int ConnectStatus = Connected(1);

        NTClient.Command("PLACE", "Sim101", "ES 03-08", "BUY", 1, "LIMIT", 1245.00, 0,   "GTC", "ax1234", "", "", "");
        int k;
        for (int i = 0; i < 100; i++)
        {
            k = 10 * (i + 1);
            Last("AUDUSD", k, 4);
            for (int j = 0; j < 999999999; j++)
            {
            }
            Console.WriteLine(k);
                        }
        }
    }
 }

please tell me the correct suggestion.

like image 638
Aditya Agarwal Avatar asked Jul 29 '12 10:07

Aditya Agarwal


2 Answers

From the WinError.h SDK header file:

//
// MessageId: RPC_E_CHANGED_MODE
//
// MessageText:
//
// Cannot change thread mode after it is set.
//
#define RPC_E_CHANGED_MODE               _HRESULT_TYPEDEF_(0x80010106L)

This is a bug in the DLL you are using. A DLL should never call CoInitializeEx() on a thread that it didn't create. It is a fairly common bug however and there's little you can do about it. But one thing, you'll have to initialize the apartment state of your thread so it matches the one that the DLL wants so the CoInitializeEx() call doesn't fail.

  • If you make this call on your program's main thread then change the attribute on your Main() method. Make it [STAThread] or [MTAThread], depending on what keeps the DLL happy. Beware that this may be detrimental to your program, you must use [STAThread] if your program creates any windows or uses any other COM object that requires an STA.

  • If you make this call on a Thread that you created then call the thread's SetApartmentState() method before you start it.

  • If you make this call from a threadpool thread, such as those created by a BackgroundWorker or Task, a delegate's BeginInvoke method or the QueueUserWorkItem() method then you cannot change the apartment type, it is always MTA. You'll have to create a Thread instead, see the previous bullet.

Also beware the apartment requirements. If the DLL is only happy with an STA (likely) then you must pump a message loop with Application.Run(). Not doing so can cause deadlock or code internal to the component just doesn't run, this can be hard to diagnose.

like image 54
Hans Passant Avatar answered Sep 22 '22 22:09

Hans Passant


Set attribute [STAThread] to your class Program.

From my understanding, whenever you need COM objects that run on STA (Single Thread Apartment) you need to specify the STAThreadAttribute to your program.

You can learn more about the STAThreadAttribute from here...

like image 40
Chibueze Opata Avatar answered Sep 20 '22 22:09

Chibueze Opata