2013-11-02 16 views
1

我想要做的事: 我在WPF(c#)中使用Web服务DLL。该DLL包含一个Web服务,您可以在我的代码中看到它为SmsSender类。调用这个类的每个方法是耗时所以我需要在其他线程中运行它的方法。程序冻结时调用component.Dispatcher.BeginInvoke()

我该怎么做: 我将DataView对象(即方法中的“返回值”)设置为DataGrid的ItemsSource。所以我用Dispatcher.BeginInvoke()

我的问题: 我的问题是使用Dispatcher.BeginInvoke()可以冻结我的程序,即使我在不​​同的线程中运行它。我想要调用方法而不冻结。是否可以定义超时?

UPDATE1:

我怎样才能设置数据视图从耗时的方法DataGrid中?

我的代码:

Action action =() => 
{ 
    SmsSender sms = new SmsSender(); 

    dgUser1.ItemsSource = sms.GetAllInboxMessagesDataSet().Tables[0].DefaultView; 
}; 

dgUser1.Dispatcher.BeginInvoke(action); 

在此先感谢

+0

这是由设计。 Dispatcher.BeginInvoke()只应该被调用来完成与UI交互的工作。 – Aron

+0

我如何重新设计我的项目?任何想法? –

+1

'Dispatcher.BeginInvoke'在创建'Dispatcher'的线程上执行委托。通常你可以使用它来从另一个线程**上更新UI线程**上的内容。由于您在委托中包含耗时的调用,这意味着所有内容都在UI线程上运行。 – pescolino

回答

2

那容易。你永远不应该阻止你的UI线程的I/O。

SmsSender sms = new SmsSender(); 
DataView result = sms.GetAllInboxMessagesDataSet().Tables[0].DefaultView 
Action action =() => 
{ 
    dgUser1.ItemsSource = result; 
}; 
dgUser1.Dispatcher.BeginInvoke(action); 

但是,这实际上不是你应该如何编写WPF应用程序。这种模式是使用WinForms模式完成的。你应该真的使用DataBinding。

数据绑定将负责所有您的Dispatcher调用。

+0

谢谢阿伦。但是我的UI被吊死了。 –

+0

我是WPF中的新成员。你会告诉我如何使用Databinding? –

+0

这里超出了快速回答的范围。请为谷歌WPF教程。任何人都会描述MVVM模式以及如何在WPF中实现它。 – Aron

1

Dispatcher.BeginInvoke在UI线程上运行委托,并且由于您已将完整的操作放在调度程序上,它将在UI线程上执行,从而导致UI挂起问题。

有很多方法可以将耗时的操作委托给后台线程,并在UI线程上调度UI调用。

简单的例子是使用BackgroundWorker。在UI线程上仅调用事件处理程序和RunWorkerCompleted处理程序上的UI操作时,将非UI物件放入此处理程序,因此需要调用UI调度程序。

小样本 -

BackgroundWorker worker = new BackgroundWorker(); 
worker.DoWork+=new DoWorkEventHandler(worker_DoWork); 
worker.RunWorkerCompleted += 
     new RunWorkerCompletedEventHandler(worker_RunWorkerCompleted); 
worker.RunWorkerAsync(); 

void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
    dgUser1.ItemsSource = (DataView)e.Result; 
}   

void worker_DoWork(object sender, DoWorkEventArgs e) 
{ 
    SmsSender sms = new SmsSender(); 
    e.Result = sms.GetAllInboxMessagesDataSet().Tables[0].DefaultView; 
} 
+0

谢谢。您应该在worker_DoWork正文中使用Dispatcher。+1为你 –

+0

_DoWork只有在“SmsSender”是UI对象的情况下才需要Dispatcher。如果不是,则不需要使用调度程序。 –