在查看各种C#异步CTP示例时,我看到一些返回的异步函数void,以及其他返回非泛型函数的异步函数Task.我可以看到为什么返回a Task<MyType>对于在异步操作完成时将数据返回给调用者很有用,但是我看到的返回类型的函数Task永远不会返回任何数据.为什么不回来void?
与此答案相关,
如果我真的想要"Fire and Forget"一个确实返回任务的方法,并且(为简单起见)让我们假设该方法不会抛出任何异常.我可以使用答案中列出的扩展方法:
public static void Forget(this Task task)
{
}
Run Code Online (Sandbox Code Playgroud)
使用这种方法,如果存在错误,则会Task引发异常,然后抛出意外异常时,异常将被吞下并被忽视.
问题:在这种情况下,扩展方法的形式是否更合适:
public static async void Forget(this Task task)
{
await task;
}
Run Code Online (Sandbox Code Playgroud)
因此编程错误会引发异常并升级(通常会导致进程失效).
在具有预期(和可忽略的)异常的方法的情况下,该方法需要变得更加精细(除此之外,关于如何构建此方法的版本的任何建议将采用可接受和可忽略的异常类型的列表? )
我在Metro应用程序的一部分中发生异常时触发了以下方法
void Model_ExceptionOccured(Exception ex)
{
var dlg = new Windows.UI.Popups.MessageDialog("An exception occured during verification: " + ex.Message, "Exception");
dlg.ShowAsync();
}
Run Code Online (Sandbox Code Playgroud)
'dlg.ShowAsync()' - 调用是异步的,但我不在乎等待结果.编译器会为它生成警告:
Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.
我应该关心吗?有什么理由我应该添加await关键字,除了摆脱警告?
如果我有一个我想要异步的普通方法:
public int Foo(){}
Run Code Online (Sandbox Code Playgroud)
我会做:
public Task<int> FooAsync(){
return Task.Run(() => Foo());
}
Run Code Online (Sandbox Code Playgroud)
我为什么这样做:
public async Task<int> FooAsync(){
return await Task.Run(() => Foo());
}
Run Code Online (Sandbox Code Playgroud)
我计划使用它的方式是:
FooAsync().ContinueWith((res) => {});
Run Code Online (Sandbox Code Playgroud)
我希望方法只是在不停止的情况下运行,但是我希望触发类似回调的东西,因此ContinueWith.但是对于第二个版本,有没有必要使用它?
经过几个小时的搜索,我仍然没有回答这个问题.我已经阅读了关于异步MVVM的这篇精彩文章并使我的viewmodel使用了工厂方法.
public class MainViewModel
{
// sic - public, contrary to the pattern in the article I cite
// so I can create it in the Xaml as below
public MainViewModel()
{
}
private async Task InitializeAsync()
{
await DoSomethingAsync();
}
public static async Task<MainViewModel> CreateAsync()
{
var ret = new MainViewModel();
await ret.InitializeAsync();
return ret;
}
}
Run Code Online (Sandbox Code Playgroud)
这对我来说很清楚,但我无法理解如何创建MainViewModel的实例并将其设置为MainPage中的datacontext.我不能简单地写
<Page.DataContext>
<viewModel:MainViewModel/>
</Page.DataContext>
Run Code Online (Sandbox Code Playgroud)
因为我应该使用MainViewModel.CreateAsync() - 方法.我不能在代码隐藏方面做到这一点,我甚至想做,因为代码隐藏 - 构造函数是常规方法,而不是异步方法.那么哪种方法可以继续?