从我的WPF应用程序调用Web服务时遇到了一个大问题。应用程序/窗口将锁定,直到该过程完成。我试图以异步方式运行它,但问题仍然存在。
目前,我正在制作的网络服务电话可以持续45-60秒。它在服务器上运行一个进程来获取大量数据。由于需要一段时间,我想让一个进度条不确定地移动,以便用户看到应用程序没有停止或任何事情(你知道他们有多么不耐烦)。
所以:
private void btnSelect_Click(object sender, RoutedEventArgs e)
{
wDrawingList = new WindowDrawingList(systemManager);
AsyncMethodHandler caller = default(AsyncMethodHandler);
caller = new AsyncMethodHandler(setupDrawingList);
// open new thread with callback method
caller.BeginInvoke((Guid)((Button)sender).Tag, MyAsyncCallback, null);
}
单击一个按钮,应用程序将创建将异步内容发布到的表单,并设置调用异步方法的异步内容。
public bool setupDrawingList(Guid ID)
{
if (systemManager.set(ID))
{
wDrawingList.Dispatcher.Invoke(DispatcherPriority.Background, new Action(() =>
{
wDrawingList.ShowForm();
Hide();
}));
return true;
}
return false;
}
这是异步方法。 showForm方法包含设置新表单的调用,包括怪物Web服务调用
public void MyAsyncCallback(IAsyncResult ar)
{
// Because you passed your original delegate in the asyncState parameter of the Begin call, you can get it back here to complete the call.
MethodDelegate dlgt = (MethodDelegate)ar.AsyncState;
// Complete the call.
bool output = dlgt.EndInvoke(ar);
try
{
// Retrieve the delegate.
AsyncResult result = (AsyncResult)ar;
AsyncMethodHandler caller = (AsyncMethodHandler)result.AsyncDelegate;
// Because this method is running from secondary thread it can never access ui objects because they are created
// on the primary thread.
// Call EndInvoke to retrieve the results.
bool returnValue = caller.EndInvoke(ar);
// Still on secondary thread, must update ui on primary thread
UpdateUI(returnValue == true ? "Success" : "Failed");
}
catch (Exception ex)
{
string exMessage = null;
exMessage = "Error: " + ex.Message;
UpdateUI(exMessage);
}
}
public void UpdateUI(string outputValue)
{
// Get back to primary thread to update ui
UpdateUIHandler uiHandler = new UpdateUIHandler(UpdateUIIndicators);
string results = outputValue;
// Run new thread off Dispatched (primary thread)
this.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Normal, uiHandler, results);
}
public void UpdateUIIndicators(string outputValue)
{
// update user interface controls from primary UI thread
sbi3.Content = "Processing Completed.";
}
感谢任何帮助或理论。我很茫然。
提前致谢
答案 0 :(得分:1)
您正在使用调度程序将方法调用到GUI线程上。这意味着即使你开始使用后台线程,你也会直接切换回GUI线程,因此GUI将无法响应。
您需要让主要工作在后台线程上进行,然后在需要更新进度条时仅使用调度程序切换到GUI线程。
答案 1 :(得分:0)
在我写这篇文章时,我实际上回答了我自己的问题,但我想在写完这篇文章的时候,我也可以发布答案以防其他人需要它。
我意识到导致问题的方法是在调度程序中,它基本上覆盖了主线程,所以即使我正在设置一个漂亮的ascynchronous线程我正在返回并运行主进程基本上是主线程
或者至少这是我的解释,任何进一步的评论都可以帮助我进一步理解。
所以我从ShowForm方法中删除了怪物调用并将其直接放入异步方法和BooYah中!窗口功能是我的。
HTH
答案 2 :(得分:0)
看起来你正在从异步方法(wat?)同步做UI的东西。此外,您的代码过于复杂,您可能会注意到这一点,因为您已经将它与自己融为一体。
我建议大幅简化这一点,主要是通过JUST异步进行Web服务调用,然后从回调中更新UI。一旦你完成了这项工作,你就可以看到所有其他让我的大脑受伤的东西。