任务是一种用于处理并发的抽象,它可以表示应该与程序的其余部分同时执行的操作。任务是Ada中的并发执行线程,表示.NET中的异步操作,也对应于Java中的线程。
我在循环中从任务工厂创建 x 个任务。当我等待所有任务完成时,这些任务会开始并完成一些工作。 我的问题是每个任务/线程都会初始化它的流...
在Task中包装外部回调(TaskCompletionSource<T>)
不幸的是,我还没有找到处理我正在处理的这个奇怪星座的现有问题: 我有一个外部 SDK,我无法更改它。通信是通过外部呼叫处理的...
我需要从同步方法(不能是异步!)并行发送多个 HTTP 调用(httpclient.SendAsync()),然后等待所有调用。另一个要求是:我必须单独处理
我需要做一件我不知道哪一个是最佳实践的事情。 在我向特定服务发送一个请求后,该请求返回 OK 并将我的请求排队。我有回电服务...
我正在学习 async/await 和 Task。所以我了解到任务基本上继承了演员。 想象我有一个模型: 类 SomeModel: ObservableObject { @Published var 下载:[Int] = [] 函数 doSo...
如何仅使用低 I/O 命令将 CSV 文件导入 MATLAB?
我正在尝试将此 csv 文件中的数据导入到包含 3 列和 524 行的 MATLAB 中。 csv 文件 我只被允许使用低 I/O 命令,例如 fopen、fscan、fprintf...所以我开始了...
在 C# 控制台应用程序中等待 Task.Run() 后,永远不会返回主线程。在 Task.Run()/Task.Factory.StartNew()/etc 之后如何返回控制台应用程序中的主线程。 谢谢!
我正在尝试编写一个小型异步Web服务器。我简单描述一下这个场景: 我的 ESP32 也是一个路由器。因此,如果我将手机连接到 WiFi,ESP32 就会传播并且
我正在尝试理解静态任务。在这里,我了解到 Thread1、2 和 3 是同时发生的,并且 _time 和 t_name 是任务内的静态变量。当我模拟代码时,我得到...
我正在编写一个端口扫描仪,无法创建流畅的用户界面。 我有一个显示扫描结果的 DataGrid: 我正在编写一个端口扫描器,无法创建流畅的 UI。 我有一个显示扫描结果的DataGrid: <DataGrid Grid.Column="0" ItemsSource="{Binding NetScanResults}" Margin="5" AutoGenerateColumns="False" IsReadOnly="True"> 然后我有一个保存扫描结果的对象。 public class NetScanResult : ObservableObject { private IPAddress ipAddress; public IPAddress IpAddress { get => ipAddress; set { SetProperty(ref ipAddress, value); OnPropertyChanged(nameof(IpAddressStr)); } } private ObservableCollection<int> openPorts; public ObservableCollection<int> OpenPorts { get => openPorts; set { SetProperty(ref openPorts, value); } } public NetScanResult() { OpenPorts = new ObservableCollection<int>(); } } 最后我有了一个扫描逻辑: [RelayCommand] public async void NetScan2Start() { try { int[] ports = { 22, 80, 443, 554, 3389, 8000, 37777 }; int timeoutMs = 2500; var stopwatch = new Stopwatch(); stopwatch.Start(); var netScanResults = await NetUtility.ScanNetwork2_Prepare(NetScanIpRangeBegin, NetScanIpRangeEnd, NetScanNetmaskSelected, ports, timeoutMs); NetScanResults = new ObservableCollection<NetScanResult>(netScanResults); var tasks = new List<Task>(); foreach (var netScanResult in NetScanResults) { foreach (var port in ports) { NetScanResult tempResult = netScanResult; int tempPort = port; var task = ScanPortAsync(tempResult, tempPort, timeoutMs); tasks.Add(task); } } await Task.WhenAll(tasks.ToArray()); stopwatch.Stop(); MessageBox.Show($"Scan finished in {stopwatch.ElapsedMilliseconds}ms"); } catch (Exception ex) { ShowInvalidData(ex.Message); return; } } private async Task ScanPortAsync(NetScanResult result, int port, int timeoutMs) { try { Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp); var connectResult = socket.BeginConnect(result.IpAddress, port, null, null); await Task.Run(() => { connectResult.AsyncWaitHandle.WaitOne(timeoutMs, true); }); if (socket.Connected) { socket.EndConnect(connectResult); Application.Current.Dispatcher.Invoke(() => { result.OpenPorts.Add(port); }); Debug.WriteLine($"{result.IpAddress}:{port} - open."); } socket.Close(); } catch (Exception ex) { Debug.WriteLine($" Exception happened =( - {ex.Message}"); } } 我开始很顺利,但一段时间后用户界面仍然冻结,我不明白为什么。 当所有扫描线程完成后,它就会解冻。 我错过了什么? 我没有从你的代码中看出你为什么使用ObservableCollection。您无需对任何地方的这些集合进行任何更改。你完全形成它们,然后才将它们归还。在我看来,这里很有可能使用“只读”集合。 我也认为不需要使用 Dispatcher 或其他细微差别来使用可变属性。扫描结果被分配给一些难以理解的东西 - 它实际上被发送到垃圾箱。同步和异步代码以一种难以想象的方式混合在一起。 我建议您从根本上改变执行任务的方法。 看一下这个示例 - 由于您没有显示与实现相关的所有代码,因此该示例基于猜测,可能并不完全准确: public class NetScanResult : ObservableObject { public IPAddress IpAddress { get; } public IReadOnlyList<int> OpenPorts { get; } public NetScanResult(IPAddress ipAddress, IEnumerable<int> openPorts) { IpAddress = ipAddress; OpenPorts = Array.AsReadOnly(openPorts?.ToArray() ?? Array.Empty<int>()); } } private async Task<int> ScanPortAsync(/*NetScanResult result,*/ IPAddress ipAddress, int port, int timeoutMs) => await Task.Run(() => { try { Socket socket = new Socket(SocketType.Stream, ProtocolType.Tcp); var connectResult = socket.BeginConnect(/*result.IpAddress,*/ipAddress, port, null, null); //await Task.Run(() => { connectResult.AsyncWaitHandle.WaitOne(timeoutMs, true); }); connectResult.AsyncWaitHandle.WaitOne(timeoutMs, true); if (socket.Connected) { socket.EndConnect(connectResult); //Application.Current.Dispatcher.Invoke(() => //{ // result.OpenPorts.Add(port); //}); Debug.WriteLine($"{/*result.IpAddress*/ ipAddress}:{port} - open."); } socket.Close(); return port; } catch (Exception ex) { Debug.WriteLine($" Exception happened =( - {ex.Message}"); return -1; } }); [RelayCommand] public async void NetScan2Start() => await Task.Run(async () => { try { int[] ports = { 22, 80, 443, 554, 3389, 8000, 37777 }; int timeoutMs = 2500; var stopwatch = new Stopwatch(); stopwatch.Start(); // I would change the method to return IP addresses. /*var netScanResults*/ IList<IPAddress> addresses = await NetUtility.ScanNetwork2_Prepare(NetScanIpRangeBegin, NetScanIpRangeEnd, NetScanNetmaskSelected, ports, timeoutMs); //NetScanResults = new ObservableCollection<NetScanResult>(netScanResults); //var tasks = new List<Task>(); var netScanTasks = new Task<NetScanResult>[addresses.Count]; //foreach (var netScanResult in NetScanResults) for (int i = 0; i < addresses.Count; i++) { var portsTasks = new Task<int>[ports.Length]; IPAddress tempAddress = addresses[i]; //foreach (var port in ports) for (int j = 0; j < ports.Length; j++) { //NetScanResult tempResult = netScanResult; int tempPort = ports[j]; /*var task*/ portsTasks[j] = ScanPortAsync(/*tempResult,*/ tempAddress, tempPort, timeoutMs); //tasks.Add(task); } netScanTasks[i] = CreateResult(); async Task<NetScanResult> CreateResult() { await Task.WhenAll(portsTasks); List<int> aports = new List<int>(ports.Length); foreach (var task in portsTasks) { int port = task.Result; if (port > 0) { aports.Add(port); } } return new NetScanResult(tempAddress, aports); }; } await Task.WhenAll(netScanTasks); NetScanResults = netScanTasks.Select(task => task.Result).ToArray(); stopwatch.Stop(); MessageBox.Show($"Scan finished in {stopwatch.ElapsedMilliseconds}ms"); } catch (Exception ex) { ShowInvalidData(ex.Message); return; } });
通过 async/await 提高 POST API 可扩展性
我开发了一个 POST API,可以将文件保存到特定目录。目前,代码同步执行。鉴于 API 可能会同时接收来自客户端的多个请求: 我会...
通过 async/await 提高 POST API 可扩展性
我开发了一个 POST API,可以将文件保存到特定目录。目前,代码同步执行。鉴于 API 可能会同时接收来自客户端的多个请求: 我会...
首先我了解到,异步任务中禁止使用ref、in、out参数。 然而,由于我有这个需求,我正在努力寻找最干净、最简单、最有效的解决方案...
我想执行一系列任务,这些任务执行一个返回具有以下结构的嵌套列表的函数: 我尝试用 SelectMany() 展平这个结构,但我得到 CS0411 The type argu...
在这个Python代码中,主要是任务和例程的示例代码: 导入异步 async def say_after(延迟,什么): 等待 asyncio.sleep(延迟) 打印(什么) 异步 def main(): 任务1 =
仅当在另一个事件内部调用事件触发方法时才会出现跨线程操作错误
目前,我有一个基于事件的日志记录系统的设置,该系统工作正常,除非在方法 Port_DataReceived(sen...
将 ValueTask 与丢弃一起使用时出现 CA2012 警告
我正在制作一个简单的 TCP 服务器,并偶然发现了 Marc Gravell 的这篇文章,其中提到了以下内容: 使用ValueTask[],除非你绝对不能,因为现有的API是Task[],甚至...
当意图标志和清单启动模式不同时,我们是否可以在启动模式下尊重意图标志值而不是清单?
Android 文档提到了相同意图标志和清单启动模式,但是当它们不同时怎么办? 因此,如果 Activity A 启动 Activity B,则 Activity B 可以在其清单中定义它如何启动
编辑 我更改了问题的标题以反映我遇到的问题,同时也提供了如何轻松实现此目标的答案。 我正在尝试使第二种方法返回 Task 而不是
我的应用程序遇到测试偶尔会失败的问题。我已经设法将问题范围缩小到这段代码片段。该代码片段包含两个异步序列,它们都观察到...