WPF / C#不要阻塞UI [英] WPF/C# Don't block the UI

查看:2315
本文介绍了WPF / C#不要阻塞UI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个现有的WPF应用程序,其中有几个部分。每一个部分是一个用户控件,实现接口。

I've an existing WPF application, which has several sections. Every section is a UserControl, that implements an interface.

该接口指定了两种方法:无效LoadData([...])布尔UnloadData()

The interface specify two methods: void LoadData([...]) and bool UnloadData().

这些方法是由UI线程调用,所以我们要做好我们的工作在BackgroundWorker的,如果它是费时。

Those method are called by the UI thread, so we need to do our work in backgroundworker if it's time consuming.

没有问题, LoadData ,因为我们可以异步更新UI。问题是与UnloadData()。

No problems with LoadData since we can update the UI asynchronously. The problem is with UnloadData().

这应该返回,如果我们真的能保持当前视图。

This should return if we can really leave the current view.

这是计算与数据的当前状态(保存/修改/无效):

This is computed with the current status of data(Saved/modified/Invalid):

  • 在保存返回true,
  • 无效询问是否要留下来节省一些 正确的数据或将不保存
  • 修改的告诉你,你可以 无论是取消更改(返回true),要么继续 编辑(返回false),可以节省您的当前数据(返回true)
  • Saved return true,
  • Invalid asks if you want to stay to save some correct data or leave without saving
  • Modified tell you that you can either cancel your change(return true), either continue to edit(return false), either save you current data(return true)

问题是与修改 - >保存。这是一个耗时的方法,所以要尊重程序的理念,我们应该在后台线程(一个繁忙的指标)运行此。

The problem is with the "Modified -> Save". This is a time consuming method, so to respect the philosophy of the application, we should run this in a background thread(with a busy indicator).

不过,如果我们只是启动线程,并进入下一个部分,它会返回真的方法调用,我们将直接启动下一个视图。

But if we just launch the thread and go to the next section, it will return "true" to the method call, and we will directly launch the next view.

在我的情况下,加载下一个视图之前我们本地保存数据可能是一个问题。

In my case, loading the next view before our local data is saved can be a problem.

所以:

有没有一种方法来等待后台线程返回真,不阻塞UI前完成?

Is there a way to wait on the background thread to finish before returning "true", WITHOUT blocking the UI?

public bool UnloadData(){
   if(...){
      LaunchMyTimeConsumingMethodWithBackgroundWorker();
      return true;//Only when my time consuming method ends
   }
   //[...]
}

重要修改 也许我并不清楚足够多:我知道如何使用一个BackgroundWorker,或TPL。我的问题是父类(其中一个叫UnloadData()是,我不能编辑类(多种原因:它在另一个DLL不会被重新加载,它已经与70多家用户控件的作品,都在不同的项目(DLL),通过反射加载。

Important EDIT Maybe I wasn't clear enought: I know how to use a BackgroundWorker, or TPL. My problem is that the parent class(the one which call the UnloadData()" is a class that I cannot edit(for multiple reasons: It's in another DLL that will not be reloaded, it already works with 70+ userControls, all in separate projects(dll), loaded by reflection.

这是不是我的选择,我并不觉得不错,但我对付它了。我主要是在寻找方法,使我的方法伺候我的方法的返回。我不知道这是否是可能的。但是我正在寻找一个解决方法,它将不遗余力的作品我几个星期。

This wasn't my choice, I don't find it good, but I've to deal with it now. I'm mostly looking for way to make my method wait on the return of my method. I'm not sure if it is possible. But I'm looking for a workaround, it will spare me weeks of works.

推荐答案

好了,现在我很兴奋,因为我想我可能已经发现了一些我自己的......

Ok now I'm excited, because I think I may have discovered something on my own...

所以,你做什么,是这样的:你创建一个DispatcherFrame,推动该帧到调度员,并在RunWorkerCompleted您设置的继续帧为false

So, what you do is this: You create a DispatcherFrame, push that frame onto the Dispatcher, and in the RunWorkerCompleted you set the Continue of the Frame to false.

这是在code到目前为止:

This is the code so far:

public void Function()
{
    BackgroundWorker worker = new BackgroundWorker();
    worker.DoWork += TimeConsumingFunction;
    var frame = new DispatcherFrame();
    worker.RunWorkerCompleted += (sender, args) =>
                                     {
                                         frame.Continue = false;
                                     };
    worker.RunWorkerAsync();
    Dispatcher.PushFrame(frame);
}

private void TimeConsumingFunction(object sender, DoWorkEventArgs doWorkEventArgs)
{
    Console.WriteLine("Entering");
    for (int i = 0; i < 3; i++)
    {
        Thread.Sleep(1000);
    }
    Console.WriteLine("Exiting");
}

private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
    Function();
    Console.WriteLine("Returns");
}

这篇关于WPF / C#不要阻塞UI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆