【发布时间】:2015-03-30 02:35:36
【问题描述】:
我有一个班级用作我所有ViewModels 的父级。它包含一个用于调用其他方法的特定方法,并在错误时显示加载消息和消息框(主要):
public class BaseViewModel
{
async public void Try(Func<Task> action, string errorMessage = null, string waitMessage = null)
{
try
{
if (waitMessage != null)
ShowLoading(waitMessage);
await action();
}
catch (Exception e)
{
ShowError(errorMessage, e);
}
finally
{
HideLoading();
}
}
}
它是异步的,所以我的ShowLoading 可以是动画之类的。
- 是否正确实施?
它将始终获得匿名 (lambda) 无参数 Tasks。我的主要问题是如何实际构建这些Tasks。假设我在ViewModelBase 的孩子中有一个Command,它在执行时调用以下方法:
private void OnMyCommandExecute()
{
Try(() =>
{
Thread.Sleep(5000);
}, "error", "please wait");
}
它无法编译,因为Not all code paths return a value in lambda expression of type 'System.Func<System.Threading.Tasks.Task>'。很明显,因为我们await 这个Func。这就引出了第二个问题:
- 在此示例中,我应该在
Try调用中添加什么内容才能使其正常工作?
我尝试了一些非常丑陋的东西,我真的希望答案会有所不同,否则可读性会很差:
Try(async () =>
{
return await Task.Factory.StartNew(() =>
{
SharePointService.Connect(Connection);
IsConnected = true;
});
}
它不会编译,但在这一点上,最好是这样。 return 上的错误:Since 'System.Func<System.Threading.Tasks.Task>' is anasyncmethod that returns 'Task', a return keyword must not be followed by an object expression. Did you intend to return 'Task<T>'?
【问题讨论】:
-
Try几乎可以肯定不是async void。应该是async Task。 -
@Servy 我盲目地相信你,我从来没有任何异步/等待的经验。我希望
Try尽可能透明地使用。 -
您的更新仍然有
async void并将所有内容卸载到ThreadPool线程(如果这是重点,那很好,但您应该注意这一点) -
@I3arnon 这不是重点,我不知道它是什么:p。这有什么问题?我更新了我的“解决方案”,这样你就可以看到我正在尝试做什么。
Try不一定是调用异步方法。 -
您不应该为您的问题添加全新的问题,也不应该为您的问题添加您自己的答案。如果你想问一个全新的问题,那就问一个新的问题。
标签: c# asynchronous mvvm lambda async-await