2

この非同期呼び出しを行う ac# .NET winforms アプリがあります。

simpleDelegate.BeginInvoke(null, null);

私の関数はデリゲートによって呼び出されており、すべてうまく機能しています。問題は、関数がワーカー スレッドで終了した後、メイン スレッドで winform の一部のコントロールを更新する必要があることです。ワーカー スレッドがこれらのコントロールを更新しようとすると、.NET が異常終了します。しかし、メインスレッドがユーザーアクションに応答し続ける必要があり、ワーカースレッドが非同期関数の呼び出しを終了した後にのみ関数 UpdateFormAfterServerCall() を呼び出します。

これを行う方法を抽象的に説明するのではなく、簡潔なコード サンプルを提供していただければ幸いです。私はすでに何百もの説明を読みましたが、正しく配線するのに苦労しています。

注: BeginInvoke の前に、次のものがあります。

simpleDelegate = new MethodInvoker(CallServer);
4

4 に答える 4

3

別のスレッドが所有する GUI を更新する場合は、別のスレッドから使​​用しますMethodInvoker

if(control.InvokeRequired)
control.Invoke( (MethodInvoker) ( ()=> updating_function() ) );
else
updating_function();
于 2012-06-08T13:53:55.197 に答える
1

Controlクラス (もForm同様Control) にはInvokeメソッドがあり、これを任意のスレッドから呼び出して、GUI スレッドでコードを実行できます。

さらに、既に GUI スレッドにいるかどうかを通知Controlする便利なプロパティがあります。InvokeRequiredたとえば、フォームに次のメソッドを作成できます。

public class MyForm
{
    // ...
    public void UpdateMe()
    {
        if (InvokeRequired)
        {
            Invoke(new Action(UpdateMe));
            return;
        }

       // Code to update the control, guaranteed to be on the GUI thread
    }
}
于 2012-06-08T13:47:10.850 に答える
1

を使用できますBackgroundWorker

BackgroundWorker bw = new BackgroundWorker();

string result = null;

bw.DoWork += (s, e) =>
{
    // Executes on background thread.
    // UI remains responsive to user activity during this time.
    result = CallServer();
};

bw.RunWorkerCompleted += (s, e) =>
{
    // Executes on UI thread upon completion.
    resultTextBox.Text = result;
};

bw.RunWorkerAsync();
于 2012-06-08T13:54:20.723 に答える
0

これがコードサンプルです[正確に欲しいもの] - http://www.yoda.arachsys.com/csharp/threads/winforms.shtml

& ここで非同期のすべてのフレーバーについて読むことができます -

http://msdn.microsoft.com/en-us/library/2e08f6yc(v=vs.100).aspx

于 2012-06-08T14:06:19.870 に答える