2014-09-03 141 views
-2

我开始异步/等待使用。我已经使用基于MVVM模式的WPF编写了简单的应用程序,但它并不像我预期的那样工作。该程序的工作原理是没有异步函数:在执行execute函数后,只有在循环函数结束后才冻结和解冻。等待/异步无法正常工作

请告诉我我错了什么。我会很感激任何反馈。 :)

这是我的modelview类。它继承自wpf类,它包含标准wpf函数的定义,如OnPropertyChanged。

public class ModelView : wpf 
{ 
    string _state; 
    public string state { get { return _state; } set { _state = value; OnPropertyChanged("state"); } } 
    public DelegateCommand work { get; set; } 

    public ModelView() 
    { 
     state = "Program started"; 

     work=new DelegateCommand(_work); 
    } 

    async void _work(object parameter) 
    { 
     state = "Working..."; 

     int j=await loop(); 

     state = "Done: " + j; 
    } 

    async Task<int> loop() 
    { 
     int i; 
     for(i=0;i<1000000000;i++); 

     return i; 
    } 
} 
+9

你几乎肯定会得到一个编译器警告,因为*告诉你*问题是什么。 – 2014-09-03 11:47:46

+0

http:// stackoverflow。com/a/25078752/2530848 – 2014-09-03 11:52:28

回答

10

代码中没有异步部分。简单地使用async关键字并非如此。使用Task.Run,而是如果你想卸载同步代码到一个不同的线程:

async void _work(object parameter) 
{ 
    status = "Working..."; 
    int j=await Task.Run(() => loop()); 
    status = "Done: " + j; 
} 

int loop() 
{ 
    int i; 
    for(i=0;i<1000000000;i++); 
    return i; 
} 

如果你确实有一个异步操作,您可以使用来代替:

async void _work(object parameter) 
{ 
    status = "Working..."; 
    await Task.Delay(1000); 
    status = "Done: " + j; 
} 

指导:如果你的“异步”方法里面没有await,它不是异步的。

+0

代码作品,谢谢你的回应! – 2014-09-03 11:55:12

5

你没有做任何异步。关键字async并不意味着“创建另一个线程”;它是相当复杂的,但基本上它允许代码继续工作另一个异步操作完成。好的例子包括异步数据库访问,文件访问,网络访问等。它还可以包括通过线程和Task.Run的异步长时间运行操作。但是:你不是那么做await没有任何不完整的代码 - 的代码在主线程上运行。当从有不完整的东西时,它只安排了一个延续

引述编译器(谈论loop法):

警告此异步方法缺乏“等待”运营商和将同步运行。考虑使用'await'操作符来等待非阻塞API调用,或者'等待Task.Run(...)'在后台线程上执行CPU绑定工作。

+0

感谢您的回应,这是我不知道的! – 2014-09-03 11:54:50

+0

@RicoW关键点:'await'永远不会创建线程;如果你正在等待的东西已经完成,它就会继续;否则它会为该“事物”添加一个延续,当* *完成时,它将从那里继续运行 – 2014-09-03 12:35:08

1

看起来问题是你的loop函数。即使您已声明它为async,但其中没有await语句,您应该看到@Marc Gravell指出的编译器警告。

该函数虽然大量循环迭代占用UI线程会导致阻塞,但它会返回最终值。

所以你循环功能实际上是一个同步功能。假设你是为了测试目的而做的,模拟async操作的好方法是使用Task.Delay。例如:

async Task<int> loop() 
{ 
    await Task.Delay(5000); 

    return 1; 
}