我需要像多個異步調用
IList<Task> Ts = new List<Task>();
Ts.Add(GetInformationFromServer(ID));
創建多個異步調用但我不什麼的線程是在等待着,我從
調用所以它應該是可以做到這樣的(舊的方式之一,但有一個新的?),從另一個電話
GetInformation(string ID) {
while (!Finish) {
Thread.Sleep(100);
}
return _Information.First(a=>a.ID==ID);
}
我當然可以保存在變量的任務,但我該如何開始呢?我如何獲得狀態?
我想我可以在另一個線程中等待它們,但是如何檢查它們是否完成?我應該自己實施嗎?
我該如何啓動它們(我應該只使用Task.WhenAll而不等待)?
UPDATE
我想通了,我要實現我自己的方式,所以答案是怎麼樣的這種方式,但我需要使用,而不是Func鍵
/// The executed elements
private IList<T> _ExecutedElements;
/// The Stack over the elements to be executed
private Stack<T> _ExecutingElements;
/// The method to be runned
private Func<object, Task<T>> _Method;
/// Should the while-loop start?
private bool _Running;
/// The Task
private Task<T> _Task;
/// Construct the class
/// <param name="Method">The function to be executed</param>
public MultiAsync(Func<object, T> Method) {
_Method = Method;
}
/// Add an element
/// <param name="Item">The item to be added</param>
public void AddItem(T Element) {
_ExecutingElements.Push(Element);
}
/// Execute the method
public async void ExecuteAsync() {
// Set it to start running
_Running = true;
// While there are elements left
while (_ExecutingElements.Count > 0) {
// Check if it is not running, and if it isn't break out
if (!_Running) { break; }
// The current element
T Element = default(T);
// Pop out the element, that has not been runned through
do { Element = _ExecutingElements.Pop(); }
while (!_ExecutedElements.Contains(Element));
// Check if there is an element, and if there is execute the method and await it
if (Element != default(T)) {
await ExecuteMethodAsync(Element);
}
}
}
/// Execute the item
/// <param name="Item">The item to be executed</param>
/// <returns>The executed item (due to reflection in FillInformation, the Item is filled)</returns>
public async Task<T> ExecuteItemAsync(T Item) {
// Check if the item has not been executed, and if it is not executed
if (!_ExecutedElements.Contains(Item)) {
// Stop the while-loop
_Running = false;
// Check if the Task is running, and if it is await it
if (_Task != default(Task) && !_Task.IsCompleted && !_Task.IsFaulted) {
await _Task;
}
// Execute the method using the specific item
await ExecuteMethodAsync(Item);
}
// Start the while-loop
ExecuteAsync();
// Return the element
return Item;
}
/// Execute the method
/// <param name="Item">The item to run</param>
/// <returns>The Task to be executed</returns>
private async Task ExecuteMethodAsync(T Item) {
// Set the Task
_Task = _Method.Invoke(Item)
// Start the task
T Element = await _Task;
// Add the item to the List
_ExecutedElements.Add(Element);
// Fill the information
FillInformation(Element);
}
調用任務是這樣的
private async void FillTasksAsync(IEnumerable<Model.Task> Tasks) {
_InfoLoader = new MultiAsync<Model.Task>(Tsk => { return GetTaskAsync(Tsk); });
foreach (var Tsk in Tasks) {
_InfoLoader.AddItem(Tsk);
}
}
你能更詳細地描述你的問題嗎?你使用多個任務來分解問題嗎?線程是否需要在某種狀態下同步?一般來說,最好不要在後臺線程中睡覺,而是等到工作準備就緒後再啓動任務。 –
是的,我正在使用異步調用來分解問題。而且他們不會同步,因爲他們正在處理不同的對象。我也許可以使用線程或線程池,然後加入它們以在準備就緒時得到通知 – The87Boy
爲什麼你不想「等待」?使用'await'是最乾淨和最受支持的解決方案。 –