2

そのため、この質問の仕方がわかりません。それが、どこでも答えを見つけるのに問題がある理由の 1 つかもしれません。

だから私のセットアップは私がクラスを持っているということです

public class Connection
{
    public static event EventHandler LogggedIn;
    public static TDConnection TDC {get;set;}
    public string Authenticate(){...}
    public static void Login()
    {
        if (Connection.TDC.Connected)
        {
            _bw = new BackgroundWorker
            {
                WorkerReportsProgress = true,
                WorkerSupportsCancellation = true
            };
            _bw.DoWork += ConnectToProject_DoWork;
            _bw.RunWorkerCompleted += ConnectToProject_RunWorkerCompleted;

            _bw.RunWorkerAsync(Connection.TDC);
        }
    }

    private static void ConnectToProject_DoWork(object o, DoWorkEventArgs e)
    {
        Connection.TDC.ConnectProjectEx(Connection.Domain, Connection.Project, Connection.UserName, Utilities.Encryption.AESEncryption.Decrypt(Connection.Password, "fsd*#(dfs(((>>>???fdjs"));
    }

    private static void ConnectToProject_RunWorkerCompleted(object o, RunWorkerCompletedEventArgs e)
    {
        LogggedIn(null, new EventArgs());
    }
}

私のメイン クラスでは、新しい Connection をインスタンス化し、Login を呼び出して、TDConnection で ALM への新しい接続を開きます。私のスレッドでは、スレッド内で既に開いているこの接続を使用したいと考えています。私が読んだことから、これを行うと、バックグラウンドワーカーの内部にいるにもかかわらず、UI スレッドでメンバーのメソッドを使用しているため、UI がブロックされます。

これを行うために私が見つけた1つの解決策:

private static void ConnectToProject_DoWork(object o, DoWorkEventArgs e)
    {
        TDConnection conn = new TDConnection();
        conn.InitConnectionEx(QCURL);

        conn.Login();

        conn.ConnectProject();

        e.Result = conn;
    }

すでにログインしており、これを行うには余分な時間がかかるため、これを行いたくありません。

Connection.TDC を _bw.RunorkerAsync(Connection.TDC) で渡そうとしましたが、これも明らかに機能しません。

既に確立されている接続を使用して、接続中に UI をブロックしない方法はありますか?

4

1 に答える 1

6

これは、COM オブジェクトに共通です。.NET クラスと同様に、多くの COM コクラスはスレッド セーフではありません。.NET では、スレッドセーフでない方法で .NET クラスを使用すると、自分の足を撃ちます。COM ではなく、スレッド セーフではないことをアドバタイズするコクラスがスレッド セーフな方法で使用されることを保証します。

これは、ワーカー スレッドからオブジェクトを作成したスレッドへのメソッド呼び出しを自動的にマーシャリングすることによって行われます。メイン スレッドで TDC オブジェクトを作成しました。したがって、BackgroundWorker から呼び出すと、メイン スレッドで呼び出しが実行されます。

これを解決する唯一の方法は、使用するスレッドと同じスレッドでオブジェクトを作成することです。これは通常、BackgroundWorker を使用できないことも意味します。Thread を作成し、その SetApartmentState() メソッドを呼び出して STA に切り替える必要がある場合があります。

于 2012-08-31T17:54:25.937 に答える