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

欢迎来到异步编程的世界,它将理智的逻辑变成看起来疯狂的意大利面条代码。

而不是这样做:

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 回答
0
if (!this.Dispatcher.CheckAccess())
    this.Dispatcher.BeginInvoke(new Action(() => settings = HtmlPage.Window.Invoke("ReadFile", new object[] { path1 }) as string));

如果检查访问返回 true 会发生什么?在那种情况下你不执行任何代码,就是这样,你的 IF 语句非常奇怪。

另外,方法开头的 thread.sleep(15sec) 的目的是什么?

如果您真的想将局部变量分配给settings该执行的结果,您可以创建一个 ManualResetEvent,将其与委托一起传递以进行调度程序调用,并在分配完成后对其进行设置。然后在调用 beginInvoke() 之后,您等待事件触发,一旦触发,您的设置将被分配。

尽管我相信这一切都需要大的重构。

于 2012-05-27T20:48:38.707 回答