自动化错误80004005

时间:2011-09-25 08:32:32

标签: c# multithreading excel com automation

我已经用这个打了几天头脑,在互联网上上下搜索。我知道有很多我不太了解Com Interop,但我已经成功构建并使用更简单的DLL与Excel。无论如何。

运行包含在DLL中的以下代码时,我在Excel VBA中得到上述错误-2147467259 80004005 Automation Error Unspecified Error

[GuidAttribute("96BE21CD-887B-4770-9FAA-CF395375AEA9")]
[ComVisibleAttribute(true)]
interface QInterface
{
    void ConnectionFill(string SQLQuery, string CONStr);
    string QueryValue(int QueryKey);
    string ConnectionValue(int ConnectionKey);
    string outputFile { get; set; }
    void ThreadTest();
}
[ClassInterfaceAttribute(ClassInterfaceType.None)]
[ProgIdAttribute("QueryThread")]
class QueryThread : QInterface
{
    DataSet QueryReturn = new DataSet();
    private ArrayList SQLList = new ArrayList();
    private ArrayList ConList = new ArrayList();
    private string OutputFile;


    public void ConnectionFill(string SQLQuery, string CONStr)
    {
        SQLList.Add(SQLQuery);
        ConList.Add(CONStr);
    }

    public string QueryValue(int QueryKey)
    {
        return SQLList[QueryKey].ToString();
    }

    public string ConnectionValue(int ConnectionKey)
    {
        return ConList[ConnectionKey].ToString();
    }


    public string outputFile
    {
        set { OutputFile = value; }
        get { return OutputFile; }
    }

    public void ThreadTest()
    {
        int i = 0;

        i = SQLList.Count;
        Thread[] myThreads;
        myThreads = new Thread[i];
        for (int t = 0; t != i; t++)
        {

            myThreads[t] = new Thread(() => ThreadRun(SQLList[t].ToString(), ConList[t].ToString()));
            myThreads[t].Name = "Thread " + t;
            myThreads[t].IsBackground = true;
            myThreads[t].Start();
            Thread.Sleep(600);
            if (t > 9)
            {
                myThreads[t - 9].Join();
            }
        }

        for (int t = 0; t != i; t++)
        {
            while (myThreads[t].IsAlive)
            {
                Thread.Sleep(20);
            }
        }

        TextWriter tw = new StreamWriter(OutputFile);
        for (int t = 0; t < QueryReturn.Tables.Count; t++)
        {
            DataTableReader DR = QueryReturn.Tables[t].CreateDataReader();
            while (DR.Read())
            {
                tw.WriteLine("{0} : {1}", DR.GetValue(0), DR.GetValue(1));
            }
        }
        tw.Close();
        QueryReturn.Dispose();
    }

    private void ThreadRun(string SQLString, string ConString)
    {
        try
        {
            OleDbConnection DBCon = new OleDbConnection(ConString);
            DBCon.Open();
            Thread.Sleep(200);
            OleDbCommand DBCmd = new OleDbCommand(SQLString, DBCon);
            OleDbDataAdapter DataAdapter = new OleDbDataAdapter(DBCmd);
            Thread.Sleep(200);
            DataAdapter.Fill(QueryReturn, Thread.CurrentThread.Name.ToString());
            DBCon.Close();
            DataAdapter.Dispose();
            DBCon.Dispose();
            DBCmd.Dispose();
        }
        finally
        {
        }
    }
}

使用此VBA代码...

Sub test()

    Dim QT As New QueryThreading.QueryThread
    Dim MyResults As String
    Dim outputfile As String
    Dim InputStuff(1, 1) As String

    InputStuff(0, 0) = "Select DISTINCT * From TrackingData;"
    InputStuff(0, 1) = "Provider =Microsoft.ACE.OLEDB.12.0;Data Source =C:\Users\Nick\Desktop\test.accdb; Persist Security Info =False;Connection Timeout=7;"
    InputStuff(1, 0) = "Select DISTINCT * From TrackingData;"
    InputStuff(1, 1) = "Provider =Microsoft.ACE.OLEDB.12.0;Data Source =C:\Users\Nick\Desktop\test2.accdb; Persist Security Info =False;Connection Timeout=7;"


    QT.ConnectionFill InputStuff(0, 0), InputStuff(0, 1)
    QT.ConnectionFill InputStuff(1, 0), InputStuff(1, 1)
    outputfile = "C:\Users\Nick\Desktop\testrun.txt"
    QT.outputfile = outputfile
    QT.ThreadTest
End Sub

它运行正常是一个纯C#控制台应用程序。工作完美,快速,没有问题。但是通过VBA我得到了错误。

我认为这与在多个线程中调用访问数据库有关。我知道那里有很多垃圾代码,它当然没有优化,我仍处于“玩转”阶段。

我已经使用了RegAsm并启用了com互操作和所有这些东西,我可以从退货中读回来就好了。所以我知道DLL工作正常,就在我填充线程并运行“ThreadTest()”时,我得到了自动化错误。

如果我再次运行它,Excel会锁定。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

您正在呼叫QT.DictionaryFill但我似乎无法在您的C#代码中找到相应的方法...如果您将呼叫更改为QT.ConnectionFill会怎样?

另一点:IIRC然后VBA在STA中运行对象 - 不确定是否支持MTA

编辑:

根据this相当旧的帖子VBA不支持多线程...