我想在初始化应用程序并显示主窗口后执行这些代码行:
if (System.IO.File.Exists("token"))
{
string[] startupStrings = Environment.GetCommandLineArgs();
await _myOneDrive.SilentLogIn();
IsActive = true;
if (startupStrings.Length > 1 && startupStrings[1] == "/a")
{
IsWorking = true;
IsActive = false;
await _myOneDrive.EjectSynchroProcedure(false);
IsActive = true;
IsWorking = false;
Application.Current.Shutdown();
}
}
不幸的是我无法做到这一点,因为我无法在我的MVVM模型构造函数中使用await
运算符。注册Loaded
事件会破坏MVVM的整体思路。我已经读过一般不使用async void
但只是在事件处理程序的逻辑等价物中。所以我的异步命令看起来像这样:
async void SilentLogin(object parameter)
{
await _myOneDrive.SilentLogin();
IsActive = true;
}
然后我在构造函数中初始化它们并将命令绑定到XAML代码中的按钮。
public MainWindowViewModel()
{
_myOneDrive = new MyOneDriveClient(PathPcDirectory, PathOneDriveDirectory, this);
LoginCommand = new RelayCommand(Login);
SilentLoginCommand = new RelayCommand(SilentLogin);
Console = "Program started";
}
它工作得很好,但我仍然无法完成初始化后运行代码的目标。我无法等待async void Login(object parameter)
命令,因为它void
不是Task
。更重要的是,我无法将其更改为Task
,因为它对RelayCommand
无效。所以我在这个循环中,并且会真正使用一些提示,技巧或指出我的错误。
答案 0 :(得分:0)
当我遇到类似的问题时,我发现了一个非常简单的AsyncRelayCommand实现。
public class AsyncRelayCommand : RelayCommand
{
private readonly Func<Task> _asyncExecute;
public AsyncRelayCommand(Func<Task> asyncExecute)
: base(() => asyncExecute())
{
_asyncExecute = asyncExecute;
}
public AsyncRelayCommand(Func<Task> asyncExecute, Action execute)
: base(execute)
{
_asyncExecute = asyncExecute;
}
public Task ExecuteAsync()
{
return _asyncExecute();
}
public override void Execute(object parameter)
{
_asyncExecute();
}
}
然后只需修改您的方法以返回Task,并用新创建的AsyncRelayCommand替换RelayCommand的用法。工作得很好。
请注意,参数的使用可能还没有成功,所以你需要一些额外的实现。对于我的情况,这是没有必要的。但是你应该得到基本的想法。