0

スレッド関数があります。この関数内では、スレッド関数で直接使用できないため、HtmlPage.Window.Invokeメソッドを使用しようとしています。BeginInvokeただし、変数settingsは常に「」です。メッセージボックスが表示されるため、BeginInvokeは正常に機能します。しかし、なぜそれは変数に何も書き込まないのですか?

Thread.Sleep(15000);
if (!this.Dispatcher.CheckAccess())
        this.Dispatcher.BeginInvoke(new Action(() => MessageBox.Show("Try to reload data!")));
string obpath = "C:\\program files\\windows sidebar\\Gadgets\\res.txt";
            string path1 = "C:\\program files\\windows sidebar\\Gadgets\\settings.txt";
string settings = "";
if (!this.Dispatcher.CheckAccess())
        this.Dispatcher.BeginInvoke(new Action(() => settings = HtmlPage.Window.Invoke("ReadFile", new object[] { path1 }) as string));
4

4 に答える 4

1

BeginInvoke は非同期で実行されます。つまり、アクションをディスパッチャーのキューに入れ、すぐに戻ります。結果が必要な場合は、 を使用できますDispatcher.Invoke

Invoke絶対に必要な場合を除き、使用は悪い習慣と見なされることに注意してください。同期を待っているスレッドで多くの時間を無駄にしています。これが起こらないようにコードをリファクタリングすることを検討してください (たとえば、このコードすべてを に渡される単一の Action 内に配置するBeginInvokeなど)。

編集

Silverlight では、Dispatcher 操作が完了するのを待つことができないため、それに依存しないようにコードをリファクタリングする必要があります。

于 2012-05-27T17:47:24.720 に答える
1

BeginInvoke は、アクションの非同期実行をスケジュールします。そのため、値が設定に割り当てられるまでに、現在の関数はおそらく終了し、設定は表示されなくなります。完了するまで待ちたい場合は、BeginInvoke の戻り値を使用する必要があります。

于 2012-05-27T17:47:36.240 に答える
0
if (!this.Dispatcher.CheckAccess())
    this.Dispatcher.BeginInvoke(new Action(() => settings = HtmlPage.Window.Invoke("ReadFile", new object[] { path1 }) as string));

check access が true を返すとどうなりますか? その場合、コードを実行しないでください。それが起こるので、IFステートメントは非常に奇妙です。

また、メソッドの先頭にある thread.sleep(15sec) の目的は何ですか?

その実行の結果にローカル変数を本当に割り当てたい場合はsettings、ManualResetEvent を作成し、それをデリゲートでディスパッチャー呼び出しに渡し、割り当てが完了した後にそれを設定します。次に、 beginInvoke() を呼び出した後、イベントが発生するのを待ちます。イベントが発生すると、設定が割り当てられます。

それにはすべて大きなリファクタリングが必要ですが、私は信じています。

于 2012-05-27T20:48:38.707 に答える
0

正常なロジックを非常識な見た目のスパゲッティ コードに変える非同期プログラミングの世界へようこそ。

これを行う代わりに:

string settings = "";
if (!this.Dispatcher.CheckAccess())
  this.Dispatcher.BeginInvoke(new Action(() => 
    settings = HtmlPage.Window.Invoke("ReadFile", new object[] { path1 }) as string));
// use settings here...  

これを行う

string settings = "";
if (!this.Dispatcher.CheckAccess())
  this.Dispatcher.BeginInvoke(new Action(() => {
    settings = HtmlPage.Window.Invoke("ReadFile", new object[] { path1 }) as string)
    // use settings here ...
  }
) else {
    settings = HtmlPage.Window.Invoke("ReadFile", new object[] { path1 }) as string)
    // use settings here ...
};
于 2012-05-28T04:07:20.090 に答える