Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
了解C&x201C;异步/等待”;Java开发人员的模式_Java_C#_Multithreading_Asynchronous_Async Await - Fatal编程技术网

了解C&x201C;异步/等待”;Java开发人员的模式

了解C&x201C;异步/等待”;Java开发人员的模式,java,c#,multithreading,asynchronous,async-await,Java,C#,Multithreading,Asynchronous,Async Await,我来自一个Java开发环境,已经开始用C#编写代码。我注意到了C#中的“异步/等待”模式,这是我在Java中从未见过的。到底是什么?我上网浏览了一段时间,找不到明确的解释来澄清我对它的理解 因此,让我们定义以下场景: 线程“T”(例如GUI线程)正在执行GUI异步函数“F” 在异步函数“F”中的某个点上,我们对“awaitable”对象“A”(很可能是任务/任务)调用“await” 然后,“await”调用将释放/产生(但不挂起)线程“T”(在本例中为GUI线程)的执行,以便在“awaitabl

我来自一个Java开发环境,已经开始用C#编写代码。我注意到了C#中的“异步/等待”模式,这是我在Java中从未见过的。到底是什么?我上网浏览了一段时间,找不到明确的解释来澄清我对它的理解

因此,让我们定义以下场景:

  • 线程“T”(例如GUI线程)正在执行GUI异步函数“F”
  • 在异步函数“F”中的某个点上,我们对“awaitable”对象“A”(很可能是任务/任务)调用“await”
  • 然后,“await”调用将释放/产生(但不挂起)线程“T”(在本例中为GUI线程)的执行,以便在“awaitable”A正在执行其工作时运行/执行一些其他任务
  • 当“可等待的”A对象完成其工作时,异步函数“F”的执行将继续。 在上面的场景中(如果我描述正确的话),哪个线程将执行“等待的”方法GUI线程或池中的其他线程?。如果它是一个池线程(不是GUI线程),并且我正在使用该方法访问GUI资源(例如按钮、标签、网格视图等),我是否会损坏GUI线程数据?请记住,我来自Java世界,那里只有一个GUI线程可以更改/操作GUI资源

  • 首先,这两种语法是不同的

    线程语法:-

    Thread thread = new Thread(() => VoidMethod("","",""));
    
    thread.Start();
    

    如果您使用此线程没有返回任何值。当整个请求完成时

    任务/任务语法:-

    public async Task<int> VoidMethod("","","")
    {
       await Task.Run(() => VoidMethod("","",""));
       return 1; 
    }
    
    公共异步任务VoidMethod(“,”,“)
    {
    等待任务。运行(()=>VoidMethod(“,”,”);
    返回1;
    }
    

    如果您使用此方法返回值。当整个请求完成时

  • await()
    可能导致异步方法返回,但其执行尚未完成,稍后将再次调用它。为了以后调用,它在返回之前进入某个事件的队列,就像Java中的线程可以调用
    Object.wait()
    ,这意味着线程进入某个事件的队列并离开处理器。异步方法离开线程,因为线程为其扮演处理器的角色

  • 当事件发生时,异步方法将恢复,也就是说,它只是在线程池的下一个可用线程上再次调用——就像wait()后的线程在下一个可用处理器上运行一样。为了不是从开始,而是从由于
    await()
    而返回的最后一个位置继续执行,将保存有关状态的信息,然后以以下形式使用:
    
    开关(状态){
    案例0:转到0';
    案例1:转到10';
    ....
    }

  • 注意这是字节码,因此可以使用
    goto
    。为了保存状态,我们需要一个对象的字段,所以async方法实际上不是一个方法而是一个类,它在第一次调用它的地方被实例化


    由于直接使用了
    goto
    ,所以很难或有时不可能用普通的C#或Java编写异步方法。但是,始终可以将异步方法的每个部分编码为单独的方法,并将这些方法用作等待事件的回调。Async/await只是异步编程的另一种语法,以及回调、参与者、CompletableFuture、java.util.concurrent.Flow等。最好从文档开始:


    或的任何博客文章。

    看看斯蒂芬·克利里的博客。埃里克·利珀特(Eric Lippert)在他的博客上也谈到了这一点(他从延续的角度开始)。看看这个:。简短回答:这取决于项目的类型,以及您是否使用过。如果您的请求需要时间。于是,用户请求另一个请求,直到第一个请求用户再次请求为止。任务/等待方法不正确,如果请求需要时间,并且用户希望这样做,线程是最好的方法。我想我理解这一点,但我的问题是,在我上面描述的场景中,什么线程用于执行等待方法?当你说“当事件发生时,异步方法被恢复,也就是说,它只是在线程池的下一个可用线程上被再次调用”-是这样吗?我认为它必须在同一个GUI线程“T”上继续-而不是在任何池线程上(C#像Java一样只有一个GUI线程吗?)当异步方法在异步等待后恢复时,它将尝试在相同的“上下文”中恢复。如果它在GUI线程上启动,它将尝试在那里继续。如果它在GUI线程之外启动,它将永远不会在GUI线程上继续。请看“它将尝试在那里继续”是什么意思“-它是否可以在不同的线程上运行,而不是在GUI线程上运行?C#中的GUI线程不是Java中的单一线程吗?