这是为什么code同步运行? [英] Why is this code running synchronously?

查看:101
本文介绍了这是为什么code同步运行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在code做它理解并发性。我有我认为是异步运行的code片段。但是,当我把调试的WriteLine语句中,我发现,这是同步运行。有人可以解释什么,我需要做不同的使用Task.Something推ComputeBB()到另一个线程?

澄清我想这code在其他线程运行ComputeBB使主线程将继续不阻塞运行。

下面是code:

  {
    //调用方法的一部分
     的Debug.WriteLine(关于调用ComputeBB);
     returnDTM.myBoundingBox =等待Task.Run(()=> returnDTM.ComputeBB());
     的Debug.WriteLine(只是叫等待ComputBB。);
     返回returnDTM;
}  私人ptsBoundingBox2d ComputeBB()
  {
     的Debug.WriteLine(启动ComputeBB。);
     秒表SW =新的秒表(); sw.Start();
     VAR点1 = this.allPoints.FirstOrDefault()值。
     VAR returnBB =新ptsBoundingBox2d(
        point1.x,point1.y,point1.z,point1.x,point1.y,point1.z);
     Parallel.ForEach(this.allPoints,
        P => returnBB.expandByPoint(p.Value.x,p.Value.y,p.Value.z)
        );
     sw.Stop();
     的Debug.WriteLine(的String.Format(计算BB了{0},sw.Elapsed));
     返回returnBB;
  }

下面是在即时窗口中的输出:

 关于调用ComputeBB
开始ComputeBB。
计算BB花00:00:00.1790574
刚打电话等待ComputBB。

澄清如果它真的异步运行它会按以下顺序:

 关于调用ComputeBB
刚打电话等待ComputBB。
开始ComputeBB。
计算BB花00:00:00.1790574

但事实并非如此。

制定
调用code有像这样的签名:私有静态异步任务loadAsBinaryAsync(字符串文件名)在一个新的水平了,不过,我尝试停止使用异步。因此,这里是调用栈​​从上到下:

 静态无效的主要(字串[] args)
  {
      aTinFile = ptsDTM.CreateFromExistingFile(TestSave.ptsTin);
      //更多的东西
  }  公共静态ptsDTM CreateFromExistingFile(字符串文件名)
  {
     ptsDTM returnTin =新ptsDTM();
     任务< ptsDTM> TSK = Task.Run(()=> loadAsBinaryAsync(文件名));
     returnTin = tsk.Result; //我怀疑问题就在这里。
     返回retunTin;
  }  私有静态异步任务< ptsDTM> loadAsBinaryAsync(字符串文件名)
  {
      //做了很多处理
     的Debug.WriteLine(关于调用ComputeBB);
     returnDTM.myBoundingBox =等待Task.Run(()=> returnDTM.ComputeBB());
     的Debug.WriteLine(只是叫等待ComputBB。);
     返回returnDTM;
  }


解决方案

  

我有我认为是异步运行的code片段。但是,当我把调试的WriteLine语句中,我发现,这是同步运行。


伺机用于异步等待的操作完成。虽然这样做,它得到控制返回给调用的方法,直到它完成。


  

我需要做不同推ComputeBB()到另一个线程


它已经运行在一个线程池线程。如果你不希望它异步等待在射后不理时尚,的等待除权pression。注意这将会对异常处理的效果。发生提供委托内部的任何例外的给定工作内被捕获,如果你没有等待,有是一个机会,他们就会去未处理的。

编辑:

让我们看看这块code的:

 公共静态ptsDTM CreateFromExistingFile(字符串文件名)
{
   ptsDTM returnTin =新ptsDTM();
   任务< ptsDTM> TSK = Task.Run(()=> loadAsBinaryAsync(文件名));
   returnTin = tsk.Result; //我怀疑问题就在这里。
   返回retunTin;
}

你当前在做的时候,你用的是同步阻塞 tsk.Result 。此外,由于某种原因,你调用 Task.Run 两次,一次在每个方法。这是不必要的。如果你想从 CreateFromExistingFile 返回你的 ptsDTM 例如,你将不得不的await 它,周围没有得到。 射后不理的执行并不关心结果,在所有。它只是想要开始它需要任何操作,如果失败或成功通常是一个非问题。这显然​​不是这里的情况

您需要做的是这样的:

 私人PtsDtm LoadAsBinary(字符串文件名)
{
   的Debug.WriteLine(关于调用ComputeBB);
   returnDTM.myBoundingBox = returnDTM.ComputeBB();
   的Debug.WriteLine(只是叫ComputeBB。);   返回returnDTM;
}

然后某处得更高调用堆栈,你实际上并不需要 CreateFromExistingFiles ,只需拨打:

  Task.Run(()=> LoadAsBinary(文件名));

当需要时。

此外,请阅读 C#命名约定的,你当前正在不继。

I am trying to understand concurrency by doing it in code. I have a code snippet which I thought was running asynchronously. But when I put the debug writeline statements in, I found that it is running synchronously. Can someone explain what I need to do differently to push ComputeBB() onto another thread using Task.Something?

Clarification I want this code to run ComputeBB in some other thread so that the main thread will keep on running without blocking.

Here is the code:

{
    // part of the calling method
     Debug.WriteLine("About to call ComputeBB");
     returnDTM.myBoundingBox = await Task.Run(() => returnDTM.ComputeBB());
     Debug.WriteLine("Just called await ComputBB.");
     return returnDTM;
}

  private ptsBoundingBox2d ComputeBB()
  {
     Debug.WriteLine("Starting ComputeBB.");
     Stopwatch sw = new Stopwatch(); sw.Start();
     var point1 = this.allPoints.FirstOrDefault().Value;
     var returnBB = new ptsBoundingBox2d(
        point1.x, point1.y, point1.z, point1.x, point1.y, point1.z);
     Parallel.ForEach(this.allPoints,
        p => returnBB.expandByPoint(p.Value.x, p.Value.y, p.Value.z)
        );
     sw.Stop();
     Debug.WriteLine(String.Format("Compute BB took {0}", sw.Elapsed));
     return returnBB;
  }

Here is the output in the immediate window:

About to call ComputeBB
Starting ComputeBB.
Compute BB took 00:00:00.1790574
Just called await ComputBB.

Clarification If it were really running asynchronously it would be in this order:

About to call ComputeBB
Just called await ComputBB.
Starting ComputeBB.
Compute BB took 00:00:00.1790574

But it is not.

Elaboration The calling code has signature like so: private static async Task loadAsBinaryAsync(string fileName) At the next level up, though, I attempt to stop using async. So here is the call stack from top to bottom:

  static void Main(string[] args)
  {
      aTinFile = ptsDTM.CreateFromExistingFile("TestSave.ptsTin");
      // more stuff
  }

  public static ptsDTM CreateFromExistingFile(string fileName)
  {
     ptsDTM returnTin = new ptsDTM();
     Task<ptsDTM> tsk = Task.Run(() => loadAsBinaryAsync(fileName));
     returnTin = tsk.Result;  // I suspect the problem is here.
     return retunTin;
  }

  private static async Task<ptsDTM> loadAsBinaryAsync(string fileName)
  {
      // do a lot of processing
     Debug.WriteLine("About to call ComputeBB");
     returnDTM.myBoundingBox = await Task.Run(() => returnDTM.ComputeBB());
     Debug.WriteLine("Just called await ComputBB.");
     return returnDTM;
  }

解决方案

I have a code snippet which I thought was running asynchronously. But when I put the debug writeline statements in, I found that it is running synchronously.

await is used to asynchronously wait an operations completion. While doing so, it yields control back to the calling method until it's completion.

what I need to do differently to push ComputeBB() onto another thread

It is already ran on a thread pool thread. If you don't want to asynchronously wait on it in a "fire and forget" fashion, don't await the expression. Note this will have an effect on exception handling. Any exception which occurs inside the provided delegate would be captured inside the given Task, if you don't await, there is a chance they will go about unhandled.

Edit:

Lets look at this piece of code:

public static ptsDTM CreateFromExistingFile(string fileName)
{
   ptsDTM returnTin = new ptsDTM();
   Task<ptsDTM> tsk = Task.Run(() => loadAsBinaryAsync(fileName));
   returnTin = tsk.Result;  // I suspect the problem is here.
   return retunTin;
}

What you're currently doing is synchronously blocking when you use tsk.Result. Also, for some reason you're calling Task.Run twice, once in each method. That is unnecessary. If you want to return your ptsDTM instance from CreateFromExistingFile, you will have to await it, there is no getting around that. "Fire and Forget" execution doesn't care about the result, at all. It simply wants to start whichever operation it needs, if it fails or succeeds is usually a non-concern. That is clearly not the case here.

You'll need to do something like this:

private PtsDtm LoadAsBinary(string fileName)
{
   Debug.WriteLine("About to call ComputeBB");
   returnDTM.myBoundingBox = returnDTM.ComputeBB();
   Debug.WriteLine("Just called ComputeBB.");

   return returnDTM;
}

And then somewhere up higher up the call stack, you don't actually need CreateFromExistingFiles, simply call:

Task.Run(() => LoadAsBinary(fileName));

When needed.

Also, please, read the C# naming conventions, which you're currently not following.

这篇关于这是为什么code同步运行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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