我有一个线程功能。在这个函数中我试图使用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));
答案 0 :(得分:1)
BeginInvoke异步执行,这意味着它将操作排入调度程序并立即返回。如果您需要结果,可以使用Dispatcher.Invoke
。
您应该注意,使用Invoke
被认为是一种不好的做法 - 除非绝对必要。你在等待同步的线程上浪费了很多时间。考虑重构您的代码,这样就不会发生(例如,将所有这些代码放在传递给BeginInvoke
的单个Action中。)
修改强>
在Silverlight中,无法等待Dispatcher操作完成,因此您必须重构代码而不依赖它。
答案 1 :(得分:1)
BeginInvoke调度异步执行的操作。因此,在将值分配给设置时,当前函数可能已退出,并且设置不再可见。如果要等到它完成,则需要使用BeginInvoke的返回值。
答案 2 :(得分: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()之后,等待事件触发,一旦触发,您的设置将被分配。
虽然这一切都需要大量的重构,但我相信。
答案 3 :(得分: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 ...
};