我有两种方法:第一种方法HTTP GET在一个地址上发送请求,第二种方法多次调用(因此,它向多个IP发送请求).这两种方法都是异步的,因此在请求远程处理时它们不会阻止代码执行.问题是,由于我的C#知识不足,我不知道如何同时发送所有请求,而不是一个接一个地发送(我的代码就是这样).那是我的代码:
public static async Task<string> SendRequest(Uri uri)
{
using (var client = new HttpClient())
{
var resp = await client.GetStringAsync(uri).ConfigureAwait(false);
return resp;
}
}
public static async Task<string[]> SendToAllIps(string req)
{
string[] resp = new string[_allIps.Length];
for (int i = 0; i < _allIps.Length; i++)
{
resp[i] = await SendRequest(new Uri(_allIps[i] + req));
}
return resp;
}
Run Code Online (Sandbox Code Playgroud)
如何在SendToAllIps不等待以前的任务结果的情况下发送请求?SendToAllIps所有请求完成后,还必须返回一组响应.据我所知,这可以通过Task.WaitAll完成,但如何在这种特殊情况下使用它?
我有这个简单的方法:
static void Extract()
{
Interlocked.Add(ref Program.n, 1);
Console.WriteLine("Currently on: " + n + " Page");
Console.WriteLine("Downloading String...Extract...");
WebClient client = new WebClient();
string html = client.DownloadString("www.something.com&page=" + n);
Console.WriteLine("Proccesing data from string... (Extract)");
}
Run Code Online (Sandbox Code Playgroud)
我想Extract()一次调用几次方法,我尝试了这个:
while(n<3411)
{
var tasks = new List<Task>();
for (int x = 0; x < 7; x++)
{
tasks.Add(Task.Factory.StartNew(new Action(Extract)));
}
Task.WaitAll(tasks);
}
Run Code Online (Sandbox Code Playgroud)
但我得到错误
严重级代码描述项目文件行抑制状态错误CS1503参数1:无法从'System.Collections.Generic.List'转换为'System.Threading.Tasks.Task'RecipeCommunity_Users C:\ Users\xxx\AppData\Local\Temporary Projects\Community_Users\Program.cs 24有效
我如何Extract()一次多次调用方法?
当谈到 .NET 中的 async/await 东西时,我有点困惑......
考虑以下方法:
public async Task DoSomething() {
IEnumerable<Task> ts = GetSomeTasks(); // Some tasks that would do some random IO stuff, or whatever
await Task.WhenAll(ts);
Console.WriteLine("All tasks completed!");
}
Run Code Online (Sandbox Code Playgroud)
是否Console.WriteLine保证在ts等待任务之后执行调用?我想我见过这样的情况,在访问任务结果之前 await 似乎不会像那样“阻塞”。适用什么规则?
我把一个控制台/表单混合程序放在一起,为了实现我正在寻找的行为,我必须在一个线程中"运行"控制台,然后用另一个启动仪表板.
我用过BackgroundWorker这个.基本上在Main方法中我启动控制台后台工作器,它在其DoWork块中执行正常的while循环以保持控制台运行.重复检查来自控制台的输入并将其传递给它相应的操作.
while (true && !Program.Shutdown)
{
String consoleInput = "";
consoleInput = Program.ReadFromConsole();
if (String.IsNullOrWhiteSpace(consoleInput))
continue;
try
{
Program.Shell(consoleInput);
}
catch (Exception ex)
{
Program.WriteToConsole(ex.Message);
}
}
Run Code Online (Sandbox Code Playgroud)
在调用启动控制台的后台工作程序之后,即ConsoleBackgroundWorker.RunWorkerAsync()调用执行加载序列的方法.
此加载序列CAN调用第二个后台工作程序,该工作程序在单独的线程内部启动仪表板.
现在我遇到的问题是加载序列结束时的循环.此循环可防止所有事务都关闭,直到两个后台工作程序都已完成(窗体关闭或控制台发送命令关闭)
while (ConsoleBackgroundWorker != null && DashboardBackgroundWorker != null)
{
/* I'm not sure of how else to fix this. But
* this corrects the high CPU usage reported
* in the Task Manager. */
System.Threading.Thread.Sleep(10);
}
Run Code Online (Sandbox Code Playgroud)
问题是CPU使用率,它一直保持在30%,这是没有你上面看到的那条线 System.Threading.Thread.Sleep(10)
我的问题是,这样可以吗?如果没有,我有什么解决方案?我注意到这确实纠正了这个问题,当应用程序没有做任何事情时,CPU现在的速度为0%.我也没有看到任何性能变化.但它还没有真正被"推",所以我不能肯定地说后者的观察.
我想我的代码有很多弱点,所以请随时分享任何想法。顺便说一句,我的主要问题是,当我尝试执行以下操作时,最后,当我想等待所有任务(通过使用 Task.WaitAll)完成以检查是否有任何异常时,仅仅因为缺少“await”运算符,它真的会让代码的任何部分同步运行吗?
public class Program
{
static bool mock = true;
static readonly object s_lockSource = new object();
static readonly CancellationTokenSource s_tokenSource = new CancellationTokenSource();
static readonly CancellationToken s_token = s_tokenSource.Token;
public static async Task Main()
{
var sw = new Stopwatch();
sw.Start();
IConfigurationRoot config = new ConfigurationBuilder()
.SetBasePath(AppDomain.CurrentDomain.BaseDirectory)
.AddJsonFile("appsettings.json").Build();
var logger = new LiteLogger(new MemoryStream(), config);
logger.Log(LogLevel.Debug, "Fetching data...");
var jsonHelper = new JsonHelper();
IAsyncIO fileService = mock ? new MockAsyncIO() : new FileService(config, s_token);
IAsyncService webService = mock …Run Code Online (Sandbox Code Playgroud) c# console-application task-parallel-library async-await .net-5
我来这里是因为我使用这段代码有一个奇怪的行为:但在此之前,我知道这样做是一个非常糟糕的做法,所以它甚至没有在现实中使用我只是想了解幕后发生的事情但我对此知之甚少。
这是有问题的代码:
int worker = 0;
int io = 0;
Console.WriteLine($"Worker thread {worker} Io thread {io}");
ThreadPool.GetAvailableThreads(out worker, out io);
ThreadPool.GetMaxThreads(out var workerThreadsMax, out var completionPortThreadsMax);
Console.WriteLine($"Worker thread {workerThreadsMax - worker} Io thread {completionPortThreadsMax - io}");
for (int i = 0; i < 100; i++)
{
Task.Run(() =>
{
Console.WriteLine(Thread.CurrentThread.ManagedThreadId + " - Running thread");
ThreadPool.GetAvailableThreads(out var worker2, out var io2);
ThreadPool.GetMaxThreads(out var workerThreadsMax2, out var completionPortThreadsMax2);
Console.WriteLine($"{Thread.CurrentThread.ManagedThreadId} - Worker thread {workerThreadsMax2 - worker2} Io thread {completionPortThreadsMax2 - io2}");
var …Run Code Online (Sandbox Code Playgroud)