C# 异步执行I命令

C# 异步执行I命令,c#,asynchronous,async-await,icommand,C#,Asynchronous,Async Await,Icommand,为了简单起见,我将我的Xamarin nUnit测试错误复制为控制台应用程序,它显示了我无法理解的相同问题。首先是有效的代码,其次是无效的代码 简单控制台应用程序 public class Working { private MyViewModel _viewModel; public Working() { Console.WriteLine("Start"); _viewModel = new MyViewModel();

为了简单起见,我将我的Xamarin nUnit测试错误复制为控制台应用程序,它显示了我无法理解的相同问题。首先是有效的代码,其次是无效的代码

简单控制台应用程序

public class Working
{

    private MyViewModel _viewModel;

    public Working()
    {
        Console.WriteLine("Start");
        _viewModel = new MyViewModel();
    }

    static void Main(string[] args)
    {
        Working prog = new Working();
        prog.Print();

    }

    public void Print()
    {
        _viewModel.NewSurveyCommand.Execute(null);
    }
}

public class MyViewModel 
{
    public MyViewModel()
    {
        NewSurveyCommand = new MyCommand(RunTest);
    }

    public ICommand NewSurveyCommand { get; private set; }

    private void RunTest()
    {
        Console.WriteLine("Running...");
        Thread.Sleep(1000);
        Console.WriteLine("Test done");
    }
}

public class MyCommand : ICommand
{
    private Action _action;

    public MyCommand(Action action)
    {
        _action = action;
    }

    public event EventHandler CanExecuteChanged;

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public void Execute(object parameter)
    {
        _action.Invoke();
    }
}
这工作正常,控制台打印运行。。。然后在一秒钟内打印完成的测试。现在,第二个异步版本只打印正在运行的

 public class Program
 {

    private ViewModel _viewModel;

    public Program()
    {
        Console.WriteLine("Start");
        _viewModel = new ViewModel();
    }

    static void Main(string[] args)
    {
        Program prog = new Program();
        prog.Go();

    }

    async void Go()
    {
        await Print();
    }

    public async Task Print()
    {
        await Task.Run( () =>  _viewModel.NewSurveyCommand.Execute(null) );
    }
}

public class ViewModel 
{
    public ViewModel()
    {
        NewSurveyCommand = new Command(async () => await RunTest());
    }

    public ICommand NewSurveyCommand { get; private set; }

    public async Task RunTest()
    {
        Console.WriteLine("Running...");
        await Task.Run( () => Thread.Sleep(1000));
        Console.WriteLine("Test done");
    }
}

public class Command : ICommand
{
    private Action _action;

    public Command(Action action)
    {
        _action = action;
    }

    public event EventHandler CanExecuteChanged;

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public void Execute(object parameter)
    {
        _action.Invoke();
    }
  }
}

因此,第二种情况在等待Task.Run(()=>Thread.Sleep(1000))时只执行部分代码;它只是让方法永远不会回来。我不明白为什么以及如何解决这个问题。有没有人遇到过同样的问题。谢谢。

主线程在
线程之前终止。Sleep(1000)已完成,所有子线程也已完成。您可以尝试添加
线程.Sleep(2000)在主方法的末尾,或者让它执行其他操作。那就行了。另外,请看:

等待一个或多个任务完成

由于任务通常在线程池线程上异步运行,因此创建和启动任务的线程将在任务实例化后继续执行。在某些情况下,当调用线程是主应用程序线程时,应用程序可能会在任务实际开始执行之前终止。在其他情况下,应用程序的逻辑可能要求调用线程仅在一个或多个任务完成执行后才继续执行。通过调用Wait方法等待一个或多个任务完成,可以同步调用线程的执行及其启动的异步任务

我希望这有帮助

编辑:
您最好使用Task.Wait()而不是Thread.Sleep(),因为您通常不知道线程何时完成:

static void Main(字符串[]args)
{
Program prog=新程序();
任务t=prog.Print();
t、 等待();
}
这不起作用,因为您在RunTest()中启动了一个新线程。然后,在Print()中创建的线程返回并取消阻止主线程,主线程返回并终止每个线程。您可以通过同步运行
RunTest()
中的
Thread.Sleep()
来解决这个问题。一切都是这样的:

public class Program
{

    private ViewModel _viewModel;

    public Program()
    {
        Console.WriteLine("Start");
        _viewModel = new ViewModel();
    }

    static void Main(string[] args)
    {
        Program prog = new Program();
        Task t = prog.Print();
        t.Wait();
    }

    async void Go()
    {
        await Print();
    }

    public async Task Print()
    {
        await Task.Run(() => _viewModel.NewSurveyCommand.Execute(null));
    }
}

public class ViewModel
{
    public ViewModel()
    {
        NewSurveyCommand = new Command(() => RunTest());
    }

    public ICommand NewSurveyCommand { get; private set; }

    public void RunTest()
    {
        Console.WriteLine("Running...");
        Thread.Sleep(1000);
        Console.WriteLine("Test done");
    }
}

public class Command : ICommand
{
    private Action _action;

    public Command(Action action)
    {
        _action = action;
    }

    public event EventHandler CanExecuteChanged;

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public void Execute(object parameter)
    {
        _action.Invoke();
    }
}

可能重复的是!!!!当我把线程。睡眠在主线程上,它有一些东西回来,所以它没有跳出主线程。