这有什么区别 - 运行“异步”动作代表了T​​ask.Run(VS默认动作代表)? [英] What difference does it make - running an 'async' action delegate with a Task.Run (vs default action delegate)?

查看:128
本文介绍了这有什么区别 - 运行“异步”动作代表了T​​ask.Run(VS默认动作代表)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图让我的头周围异步/等待,以为我没理解,使用方法的几件事情。但还是不太清楚什么是场景中的实际好处如下图所示。

看那Task.Run使用。第一种方法使用一个普通的委托,并使用了Thread.Sleep但第二个采用异步代表和Task.Delay。

我的问题是:如何这有什么区别这个方法(或没有)?

该方法本身是一个异步方法。在code是创建一个单独的线程(通过Task.Run),并针对这个讨论有没有别的比执行该委托做其他的。所以,即使它与Task.Delay的计谋产生,什么是在这种情况下使用,因为线程反正不用于别的即使它只是使用了Thread.Sleep,该线程将仍背景下孤立的线程切换到屈服于其他线程的处理器。

  //任务线程使用异步委托
公共异步任务<布尔> RetrySendEmail(MailMessage消息)
{
      布尔emailSent = FALSE;
      等待(Task.Run(***异步()*** =>
      {
            的for(int i = 0;我3;;我++)
            {
                 如果(emailSent)
                      打破;
                 其他
                      //重试前等待5秒
                      ***等待Task.Delay(5000); ***

                 尝试
                 {
                      Smtphost.Send(消息);
                      emailSent = TRUE;
                      打破;
                 }
                 赶上(例外五){emailSent = FALSE; //记录; }
            }
            返回emailSent;
      }));
}

//任务线程使用普通的委托
公共异步任务<布尔> RetrySendEmail(MailMessage消息)
{
      布尔emailSent = FALSE;
      等待(Task.Run(***()*** =>
      {
            的for(int i = 0;我3;;我++)
            {
                 如果(emailSent)
                      打破;
                 其他
                      //重试前等待5秒
                      *** Thread.sleep代码(5000); ***

                 尝试
                 {
                      Smtphost.Send(消息);
                      emailSent = TRUE;
                      打破;
                 }
                 赶上(例外五){emailSent = FALSE; //记录; }
            }
                 返回emailSent;
        }));
}
 

解决方案
  

我的问题是:如何这有什么区别这个方法(或   事实并非如此)?

一对夫妇的差异

  1. 使用异步委托在 Task.Run 意味着你实际上运行任务&LT ;任务> 。这是从你隐藏的事实, Task.Run 是异步了解和解开内的任务给你,东西 Task.Factory.StartNew 没做
  2. 当您使用异步委托与 Task.Run ,创建一个新的线程,然后得到控制,一旦你打等待任务.Delay 。延续将运行在任意线程池线程。 Additionaly,委托由编译器转变成一个状态机。

    通过正常的委托,你创建一个线程,同步阻止它持续5秒钟,然后继续在你离开的地步。任何国家机器,不屈服。


  

所以,即使它与上Task.Delay一个的await产生,什么是在这种情况下的使用中,由于线程是反正一个孤立线   不用于别的即使它只是使用了Thread.Sleep时,   线程仍然上下文切换产生对其他线程的   处理器。

使用异步 Task.Run 可当你想要做的CPU和IO绑定工作,都在一个专门的线程。你是正确的思维是,异步委托的产量后,将返回上一个任意线程。不过,如果你没有使用 Task.Run 异步从一个线程有一个自定义的执行方法同步上下文连接(如WinformsSynchronizationContext),之后的任何作品等待将产生回UI消息循环,除非你使用 ConfigureAwait(假)

说实话,我还没有看到,其中 Task.Run 异步用于许多场景正确。但它有时是有意义的。

I am trying to get my head around async/await and thought I did understand few things about the usage. But still not quite clear what would be the actual benefit in a scenario like below.

Look at the Task.Run usage. The first method uses a normal delegate and uses Thread.Sleep but the second one uses 'async' delegate and Task.Delay.

My question is : how does this make any difference to this method (or it does not) ?

The method itself is an async method. The code is creating a separate thread (via Task.Run) and this thread has nothing else to do other than executing that delegate. So, even if it yields with an await on Task.Delay, what is the use in this scenario, since the thread is anyways a isolated thread not used for anything else and even if it just uses Thread.Sleep, the thread would still context switch to yield to other threads for the processor.

// The task thread uses a async delegate
public async Task<bool> RetrySendEmail(MailMessage message)
{
      bool emailSent = false;
      await (Task.Run(***async ()*** =>
      {
            for (int i = 0; i < 3; i++)
            {
                 if (emailSent)
                      break;
                 else
                      // Wait for 5 secs before trying again
                      ***await Task.Delay(5000);***

                 try
                 {
                      Smtphost.Send(message);
                      emailSent = true;
                      break;
                 }
                 catch (Exception e) { emailSent = false; // log; }
            }
            return emailSent;
      }));
}

// The task thread uses a normal delegate 
public async Task<bool> RetrySendEmail(MailMessage message)
{
      bool emailSent = false;
      await (Task.Run(***()*** =>
      {
            for (int i = 0; i < 3; i++)
            {
                 if (emailSent)
                      break;
                 else
                      // Wait for 5 secs before trying again
                      ***Thread.Sleep(5000);***

                 try
                 {
                      Smtphost.Send(message);
                      emailSent = true;
                      break;
                 }
                 catch (Exception e){ emailSent = false; // log; }
            }
                 return emailSent;
        }));
}

解决方案

My question is : how does this make any difference to this method (or it does not) ?

A couple of differences

  1. Using an async delegate inside Task.Run means that you actually run a Task<Task>. This is hidden from you by the fact that Task.Run is async aware and unwraps the inner task for you, something that Task.Factory.StartNew didn't do
  2. When you use an async delegate with Task.Run, you create a new thread, then yield control once you hit await Task.Delay. The continuation will run on an arbitrary thread-pool thread. Additionaly, the delegate is transformed into a state-machine by the compiler.

    With the normal delegate, you create a thread, synchronously block it for 5 seconds, and then continue at the point you left off. No state-machines, no yielding.


So, even if it yields with an await on Task.Delay, what is the use in this scenario, since the thread is anyways a isolated thread not used for anything else and even if it just uses Thread.Sleep, the thread would still context switch to yield to other threads for the processor.

The use of async with Task.Run can be when you want to do both CPU and IO bound work, all in a dedicated thread. You're right in thinking that after the async delegate yields, it returns on an arbitrary thread. Though, if you hadn't used Task.Run, and the async method executed from a thread that had a custom synchronization context attached (such as WinformsSynchronizationContext), any work after the await would yield back to the UI message loop, unless you used ConfigureAwait(false).

To tell the truth, I haven't seen that many scenarios where Task.Run and async are used correctly. But it does make sense at times.

这篇关于这有什么区别 - 运行“异步”动作代表了T​​ask.Run(VS默认动作代表)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆