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

时间:2012-05-27 17:06:14

标签: c# silverlight

我有一个线程功能。在这个函数中我试图使用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 个答案:

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