1

アプリケーション(WinForms)があります。単にデータを取得し、そのデータに対して何らかの処理を行い、その結果をクラウド ストレージにアップロードするだけです。私は現在、クラウドストレージでの認証を処理するサードパーティのコードを使用しています。このコードは、ブラウザー コントロールをホストする WinForm を作成します。このブラウザー コントロールは、アプリケーションがクラウド ストレージを使用するための資格情報とアクセス許可をユーザーがまだ提供していない場合に表示されます。プログラムが動作する前に、既に認証されていることを確認したいので、プログラム (Program.cs) の Main() ループで、サード パーティ ライブラリを使用してクラウド ストレージで認証したいと考えています。そして、完了するまで実際のコード (//myCode) の実行をブロックします。「残念ながら」ライブラリは非同期であり、私は今日のほとんどの時間を自分の動作を得るために費やしました.

だから私はこのようなものを持っています

static void Main(string[] args)
{
OAuth.LoginAuthAsync("clientID", "client_secret", ...) 
//Don't want to get here until LoginAuthAsync is done 
application.run(myForm); //myCode
}

しかし、これにより Web ブラウザーがポップアップし、コードが実行されます。これは、Web OAuth.LoginAuthAsync が完了した後にのみ実行したいと考えています。

私は TPL ライブラリ全体の専門家ではありませんが、動作するはずなのに動作しないと思われるものでしばらく遊んでみました。私はもう試した:

私はもう試した

        Task.Run(async () =>
            {
                OAuth.LoginAuthAsync("123456", "asdasd", ...));
    ).Wait();

サードパーティのライブラリでエラーをスローする

System.Threading.ThreadStateException: 現在のスレッドがシングル スレッド アパートメントにないため、ActiveX コントロール '8856f961-340a-11d0-a96b-00c04fd705a2' をインスタンス化できません。System.Windows.Forms.WebBrowserBase..ctor (文字列 clsidString) で System.Windows.Forms.WebBrowser..ctor() で

それで、私は試しました

        Thread tx = new Thread(() => OAuth.LoginAuthAsync("123456","asdasd", ……..));
        tx.SetApartmentState(ApartmentState.STA);
        tx.Start();
        tx.Join();

しかし、それはウィンドウをポップアップするだけですぐに消え、//myCode が実行されます。

ここで私に何ができるか、どんな体にもアイデアがあります。メソッドをmyForm _Loadイベント (application.run から呼び出された myForm) 内に移動しようとしましたが、同じ問題があります。

どうもありがとう

PS私はこれ以上サードパーティのライブラリを使用したくありません。

4

1 に答える 1

1

from から返された のWait()メソッドを使用して、ブロックしてコードが完了するのを待つことができます。これはコンソール アプリでは機能しますが、GUI/ASP アプリではデッドロックが発生する可能性があります。TaskOAuth.LoginAuthAsync

static void Main(string[] args)
{
    OAuth.LoginAuthAsync("clientID", "client_secret", ...).Wait();

    //Don't want to get here until LoginAuthAsync is done 
    application.run(myForm); //myCode
}

GUI アプリの場合は、関連するメソッドを作成してから呼び出しを行うのがasync最善awaitですOAuth.LoginAuthAsyncMainasync. メソッド内にメソッドを移動すると、呼び出しmyForm_Loadを実行できるはずです。await

public async void myForm_Load(object o, EventArgs e)
{ 
     await OAuth.LoginAuthAsync("clientID", "client_secret", ...);
}

私の意見では、それがより良い解決策です。

于 2015-02-23T03:08:08.513 に答える