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 异步执行,这意味着它将操作排队到调度程序中并立即返回。如果需要结果,可以使用 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 ...
};