goo*_*ate 5 linq ienumerable task-parallel-library
如何合并List<T>基于TPL的任务以便以后执行?
public async IEnumerable<Task<string>> CreateTasks(){ /* stuff*/ }
Run Code Online (Sandbox Code Playgroud)
我的假设是.Concat()......
void MainTestApp() // Full sample available upon request.
{
List<string> nothingList = new List<string>();
nothingList.Add("whatever");
cts = new CancellationTokenSource();
delayedExecution =
from str in nothingList
select AccessTheWebAsync("", cts.Token);
delayedExecution2 =
from str in nothingList
select AccessTheWebAsync("1", cts.Token);
delayedExecution = delayedExecution.Concat(delayedExecution2);
}
/// SNIP
async Task AccessTheWebAsync(string nothing, CancellationToken ct)
{
// return a Task
}
Run Code Online (Sandbox Code Playgroud)
我想确保这不会产生任何任务或评估任何东西.事实上,我想我在问"逻辑上执行IQueryable到返回数据的东西"?
背景
由于我正在进行递归,并且我不想在正确的时间之前执行此操作,如果多次调用,合并结果的正确方法是什么?
如果重要,我正在考虑运行此命令来启动var AllRunningDataTasks = results.ToList();此代码后面的所有任务:
while (AllRunningDataTasks.Count > 0)
{
// Identify the first task that completes.
Task<TableResult> firstFinishedTask = await Task.WhenAny(AllRunningDataTasks);
// ***Remove the selected task from the list so that you don't
// process it more than once.
AllRunningDataTasks.Remove(firstFinishedTask);
// TODO: Await the completed task.
var taskOfTableResult = await firstFinishedTask;
// Todo: (doen't work)
TrustState thisState = (TrustState)firstFinishedTask.AsyncState;
// TODO: Update the concurrent dictionary with data
// thisState.QueryStartPoint + thisState.ThingToSearchFor
Interlocked.Decrement(ref thisState.RunningDirectQueries);
Interlocked.Increment(ref thisState.CompletedDirectQueries);
if (thisState.RunningDirectQueries == 0)
{
thisState.TimeCompleted = DateTime.UtcNow;
}
}
Run Code Online (Sandbox Code Playgroud)
以下是一种合并数据的黑客方法...我不喜欢在 Main 或此示例的其他一些方面必须使用“nothingList”,但它似乎完成了工作并允许我合并待处理的任务。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
// Add a using directive and a reference for System.Net.Http.
using System.Net.Http;
// Add the following using directive.
using System.Threading;
namespace ProcessTasksAsTheyFinish
{
public partial class MainWindow : Window
{
// Declare a System.Threading.CancellationTokenSource.
CancellationTokenSource cts;
List<IEnumerable<Task>> launchList = new List<IEnumerable<Task>>();
public MainWindow()
{
InitializeComponent();
List<string> nothingList = new List<string>();
nothingList.Add("whatever");
cts = new CancellationTokenSource();
delayedExecution =
from str in nothingList
select AccessTheWebAsync("", cts.Token);
List<string> nothingList2 = new List<string>();
nothingList2.Add("whatever");
delayedExecution2 =
from str in nothingList2
select AccessTheWebAsync("1", cts.Token);
launchList.Add(delayedExecution);
launchList.Add(delayedExecution2);
delayedExecution = delayedExecution.Concat(delayedExecution2);
}
IEnumerable<Task> delayedExecution = null;
IEnumerable<Task> delayedExecution2 = null;
private async void startButton_Click(object sender, RoutedEventArgs e)
{
resultsTextBox.Clear();
// Instantiate the CancellationTokenSource.
try
{
// ***Set up the CancellationTokenSource to cancel after 25 seconds.
//cts.CancelAfter(250000);
var test = delayedExecution;// AccessTheWebAsync("", cts.Token);
var testList = test.ToList();
while (testList.Count() > 0)
{
var firstFinishedTask = await Task.WhenAny(testList);
testList.Remove(firstFinishedTask);
await firstFinishedTask;
}
resultsTextBox.Text += "\r\nDownloads complete.";
}
catch (OperationCanceledException tee)
{
resultsTextBox.Text += "\r\nDownloads canceled.\r\n";
}
catch (Exception)
{
resultsTextBox.Text += "\r\nDownloads failed.\r\n";
}
cts = null;
}
private void cancelButton_Click(object sender, RoutedEventArgs e)
{
if (cts != null)
{
cts.Cancel();
}
}
async Task<string> AccessTheWebAsync(string nothing, CancellationToken ct)
{
// CHANGE THIS VALUE TO CONTROL THE TESTING
bool delayConversionOfQueryToList = false;
HttpClient client = new HttpClient();
// Make a list of web addresses.
List<string> urlList = null;
if (nothing == "1")
{
urlList = SetUpURLList2();
}
else urlList = SetUpURLList();
// ***Create a query that, when executed, returns a collection of tasks.
IEnumerable<Task<int>> downloadTasksQuery =
from url in urlList select ProcessURL(url, client, ct);
// DEBUG!!!
if (delayConversionOfQueryToList == true)
{
await Task.Delay(10000);
resultsTextBox.Text += String.Format("\r\nDelay of IQueryable complete. Tip: Did you see any IsRunning messages?");
}
// ***Use ToList to execute the query and start the tasks.
List<Task<int>> downloadTasks = downloadTasksQuery.ToList();
// DEBUG!!!
if (delayConversionOfQueryToList == false)
{
await Task.Delay(10000);
resultsTextBox.Text += String.Format("\r\nDelay of .ToList() complete. Tip: Did you see any IsRunning messages?");
}
// ***Add a loop to process the tasks one at a time until none remain.
while (downloadTasks.Count() > 0)
{
// Identify the first task that completes.
Task<int> firstFinishedTask = await Task.WhenAny(downloadTasks);
resultsTextBox.Text += String.Format("\r\nID {0}", firstFinishedTask.Id);
// ***Remove the selected task from the list so that you don't
// process it more than once.
downloadTasks.Remove(firstFinishedTask);
// Await the completed task.
int length = await firstFinishedTask;
resultsTextBox.Text += String.Format("\r\nLength of the download: {0}", length);
}
return nothing;
}
private List<string> SetUpURLList()
{
List<string> urls = new List<string>
{
"http://msdn.microsoft.com",
"http://msdn.microsoft.com/library/windows/apps/br211380.aspx",
"http://msdn.microsoft.com/en-us/library/hh290136.aspx",
"http://msdn.microsoft.com/en-us/library/dd470362.aspx",
"http://msdn.microsoft.com/en-us/library/aa578028.aspx",
"http://msdn.microsoft.com/en-us/library/ms404677.aspx",
"http://msdn.microsoft.com/en-us/library/ff730837.aspx"
};
return urls;
}
private List<string> SetUpURLList2()
{
List<string> urls = new List<string>
{
"http://www.google.com",
};
return urls;
}
async Task<int> ProcessURL(string url, HttpClient client, CancellationToken ct)
{
resultsTextBox.Text += String.Format("\r\nIS RUNNING {0}", url);
// GetAsync returns a Task<HttpResponseMessage>.
HttpResponseMessage response = await client.GetAsync(url, ct);
// Retrieve the website contents from the HttpResponseMessage.
byte[] urlContents = await response.Content.ReadAsByteArrayAsync();
// Thread.Sleep(3000);
// await Task.Delay(1000, ct);
return urlContents.Length;
}
}
}
// Sample Output:
IS RUNNING http://msdn.microsoft.com
IS RUNNING http://msdn.microsoft.com/library/windows/apps/br211380.aspx
IS RUNNING http://msdn.microsoft.com/en-us/library/hh290136.aspx
IS RUNNING http://msdn.microsoft.com/en-us/library/dd470362.aspx
IS RUNNING http://msdn.microsoft.com/en-us/library/aa578028.aspx
IS RUNNING http://msdn.microsoft.com/en-us/library/ms404677.aspx
IS RUNNING http://msdn.microsoft.com/en-us/library/ff730837.aspx
IS RUNNING http://www.google.com
Delay of .ToList() complete. Tip: Did you see any IsRunning messages?
ID 1
Length of the download: 48933
ID 2
Length of the download: 375328
ID 3
Length of the download: 220428
ID 4
Length of the download: 222256
ID 5
Length of the download: 229330
ID 6
Length of the download: 136544
ID 7
Length of the download: 207171
Delay of .ToList() complete. Tip: Did you see any IsRunning messages?
ID 8
Length of the download: 43945
Downloads complete.
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
510 次 |
| 最近记录: |