簡體   English   中英

從異步任務方法返回“正常”變量

[英]Return "normal" variable from async Task Method

在我的一個方法中,我想創建一個這樣的汽車:

public string[] CreateCar()
{
    string[] wheels = CreateWheels();

    // Also add motor and other stuff here
    string[] motor = ...;

    return new string[][]{ wheels, motor, ... };
}

這里創建了四個輪子,它們不相互依賴。 因此,我可以將它們放在多個tasks ,並進行並行處理。 (在我的真實代碼中,這在並行 for 循環中是不可能的)

public string[] CreateWheels()
{
    Task FL = Task.Run(() => CreateWheel("front left");
    Task FR = Task.Run(() => CreateWheel("front right");
    Task BL = Task.Run(() => CreateWheel("back left");
    Task BR = Task.Run(() => CreateWheel("back right");

    // Here I really want to wait for all wheels to be created!
    // STOP THE PROCESS HERE UNTIL ALL WHEELS ARE COMPLETED!!!
    string[] wheels = await Wask.WhenAll(FL, FR, BL, BR); 

    return wheels;
}

一個單一的輪子是這樣創建的:

public string CreateWheel(string position)
{
    // Here a wheel is created, whatever it takes :)
    return "wheel " + position;
}

我現在的問題如下:
為了編譯代碼,它迫使我將CreateWheels標記為async CreateWheels 否則我不能使用await
⇒ 但這迫使我將其返回值更改為Task<string[]>
⇒ 但是,然后我需要在CreateCar CreateWheels()中的CreateWheels()前面放置一個await以獲取字符串數組而不是任務本身

⇒ 然后循環重復,因為現在CreateWheels有一個await ,迫使我使其async ......等等,等等......

這個循環一直往上重復,直到最后到了一個void方法,在那里你不需要用await提取返回值

如果我只想等待所有車輪在標記點完成,有什么方法可以擺脫這個循環?

如果您希望這是同步的,那么Task.WaitAll可能會有所幫助,即

Task.WaitAll(FL, FR, BL, BR);
var wheels = new[] {FL.Result, FR.Result, BL.Result, BR.Result};

如果您希望這是異步的,則需要使方法async [Value]Task<string[]> ,並在整個過程中傳播異步性。 異步是粘性的——它堅持一切; 但:

string[] wheels = await Task.WhenAll(FL, FR, BL, BR);

但是,坦率地說,我懷疑在這種情況下不需要任何一種; 並行並不便宜-並且可能是加入了很多更多的開銷比它的價值在這里。

可以通過使用Task.Run啟動多個任務來實現並行Task.Run ,但是為什么不使用像PLINQ庫這樣的專門工具來完成這項工作呢? 您不僅可以避免使用Task.Result屬性,該屬性在與await結合時會導致嚴重的死鎖而臭名昭著,而且您還可以獲得定義最大並行度作為獎勵的能力:

var wheelNames = new[] { "front left", "front right", "back left", "back right" };
string[] wheels = wheelNames
    .AsParallel()
    .AsOrdered()
    .WithDegreeOfParallelism(4)
    .Select(x => CreateWheel(x))
    .ToArray();
string[] wheels = Wask.WhenAll(FL, FR, BL, BR).Result;

會做你想做的。 這些單獨的任務仍將並行運行。

缺點是您的調用線程將阻塞,直到這些任務全部解決。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM