这个Task.Factory.FromAsync的实现实际上是在异步运行吗?

本文关键字:异步 运行 实际上 Factory Task FromAsync 实现 这个 | 更新日期: 2023-09-27 18:15:38

我从WinForm测试,因为我听说控制台应用程序对async的东西撒谎:

List<string> lstFiles = new List<string>();         
lstFiles = FillList();   // File list with all files to Process                
List<PSObject> lstRetVals = new List<PSObject>();
try
{
    foreach (string strFullFile in lstFiles)
    { lstRetVals.AddRange(clsOne.TestFifteen(strFullFile)); }
}
catch (Exception ex)
{throw ex ;}

这个中间方法基本上只是在这里,因为我正在测试await的正确使用。看来不使用await和阻塞对我来说是最好的…

        //public async Task<int> TestFifteen(string  pStrFullFilePathFileNm)    
    // as you see from this previous Signature
      public List<PSObject> TestFifteen(string pStrFullFilePathFileNm)            
    {         
        int iRetVal = -99;
        Task<PSDataCollection<PSObject>> tRetval = null;
        List<PSObject> lstPsObjs = null;
        try
        {
            tRetval = TestFifteenSub(pStrFullFilePathFileNm);
            lstPsObjs = tRetval.Result.ToList();
        }
        catch (Exception zz)
        { throw zz; }
        //  Debug.WriteLine("Is this OK");
        foreach (PSObject psobj in tRetval.Result)
        {
            iRetVal = tRetval.Result.Count;
            // return  Task<PSDataCollection<PSObject>>  or   
        }
        //return iRetVal;
        return lstPsObjs;
    }

最后是关注的区域:----Task.Factory。FromAsync----我必须使用这个,因为Powershell API还没有TAP实现。这一行实际上是异步的吗?实际上开始一个新的线程?

public Task<PSDataCollection<PSObject>> TestFifteenSub(string p_scriptText)
    {
        //var tcs = new TaskCompletionSource<int>();
        PowerShell ps = PowerShell.Create();
        ps.AddScript(p_scriptText);
        Task<PSDataCollection<PSObject>> plpl;
        PSDataCollection<PSObject> psDtaColOfpsDtaObjs = null;
        List<PSObject> lstPSObjs = null;
        try
        {
            plpl = Task.Factory.FromAsync(ps.BeginInvoke(), pResult => ps.EndInvoke(pResult)); //  BLOCKS here No await Keyword so it waits for this call to complete
            //await taskQue;        
            psDtaColOfpsDtaObjs = plpl.Result;
            lstPSObjs = plpl.Result.ToList();
            //  lstPSObjs = convertedObject.ToList();
        }
        catch (Exception vv)
        { throw vv; }
        // return plpl.Result;           
        return plpl;
    }

这个Task.Factory.FromAsync的实现实际上是在异步运行吗?

我从WinForm测试,因为我听说控制台应用程序对异步的东西撒谎

确实,用于向控制台读取和写入控制台 api不能正确地使用异步实现,但这不会影响任何其他api。异步控制台唯一的另一个问题是,你必须有一个单一的顶级阻塞调用,所以主线程不会退出。

似乎不使用await和阻塞对我的使用是最好的

如果你正在编写控制台应用程序,那么阻塞是可以的。如果你正在编写一个winforms应用程序,你可能需要重新评估这一点;async对于保持UI线程空闲非常有用。

这行实际上是Async吗?实际上开始一个新的线程?

正如其他人所评论的,异步方法(通常)不启动新线程。事实上,恰恰相反:异步方法释放了调用线程。是的,它是异步的。

也就是说,调用异步方法然后立即阻塞返回任务上的(通过调用Task<T>.Result)是相当没有意义的,因为PowerShell也有一个同步的Invoke方法。如果无论如何都要阻塞,那么不妨调用同步方法。 事实上,如果你总是阻塞,为什么要使用asyncawait呢?你应该使用同步方法。
public PSDataCollection<PSObject> TestFifteenSub(string p_scriptText)
{
  PowerShell ps = PowerShell.Create();
  ps.AddScript(p_scriptText);
  return ps.Invoke();
}
public List<PSObject> TestFifteen(string pStrFullFilePathFileNm)            
{         
  PSDataCollection<PSObject> retval = null;
  List<PSObject> lstPsObjs = null;
  retval = TestFifteenSub(pStrFullFilePathFileNm);
  lstPsObjs = retval.ToList();
  return lstPsObjs;
}