Search code examples
c#mql5

How can I handle stathreadattribute error on C#?


I coded following C# code and create a "dll" from it and import in mql5 to run it. but after running it when I click inside dialog box.I confronted following error which I couldn't solve it:

"Current thread must be set to single thread apartment (STA) mode before OLE calls can be made. Ensure that your Main function has STAThreadAttribute marked on it"

Main C# code is:

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


namespace mainProg
{
    public static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]

        public static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form2());
        }
    }
}

and inside form2 I have:

   private void textBox1_Click(object sender, EventArgs e)
    {

        textBox1.SelectAll();
        Clipboard.SetText(textBox1.Text);
    }

in MQL5 I have :

#import "mainProg.dll"

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
 Program::Main();
  }

Solution

  • Ciao, this problem appears because, you set set attribute [STAThread] in Main but the Form is managed by another thread that is initialized with ApartmentState.MTA by default.

    Try to add this code on Form loading:

    private void Form2_Load(object sender, EventArgs e)
    {
        System.Threading.Thread.CurrentThread.ApartmentState = System.Threading.ApartmentState.STA;
    }
    

    Should solve your problem.

    EDIT

    Now I saw that VS says "System.Threading.Thread.CurrentThread.ApartmentState is obsolete". So, it's better to use:

    private void Form2_Load(object sender, EventArgs e)
    {
        System.Threading.Thread.CurrentThread.SetApartmentState(System.Threading.ApartmentState.STA);
    }