beginInvoke 有效,但不将值写入变量

本文关键字:变量 有效 beginInvoke | 更新日期: 2023-09-27 18:35:31

我有一个线程函数。在这个函数中,我正在尝试将HtmlPage.Window.Invoke方法与BeginInvoke一起使用,因为我不能直接在线程函数中使用它。但变量settings始终是"。它显示消息框,因此开始调用工作正常。但是为什么它不向变量写入任何内容?

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));

beginInvoke 有效,但不将值写入变量

BeginInvoke 计划异步执行的操作。 因此,当值分配给设置时,当前函数可能已退出,设置不再可见。 如果要等到它完成,则需要使用 BeginInvoke 的返回值。

BeginInvoke 异步执行,这意味着它将操作排队到调度程序中并立即返回。如果需要结果,可以使用 Dispatcher.Invoke

您应该注意,除非绝对必要,否则使用 Invoke 被认为是一种不好的做法。您在等待同步的线程上浪费了大量时间。考虑重构您的代码,这样就不会发生这种情况(例如,将所有这些代码放在传递给BeginInvoke的单个操作中。

编辑

在 Silverlight 中,不可能等待调度程序操作完成,因此您必须重构代码以不依赖于它。

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

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

另外,在方法开始时线程.睡眠(15秒)的目的是什么?

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

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

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

而不是这样做:

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 ...
};