- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我才刚刚开始学习C#线程和并发集合,并且不确定提出问题的合适术语,因此我将简要介绍我想做的事情。在这一点上,我对此主题的掌握最多是基本的。按照我的设想,下面的方法是否还可行?
class TestArgs args {
ConcurrentBag<UrlInfo> myCollection { get; set; }
System.Uri currentUrl { get; set; }
}
ConcurrentQueue<UrlInfo> Urls = new ConncurrentQueue<UrlInfo>();
// populate the Urls queue
<snip>
// initialize the bad urls collection
ConcurrentBag<UrlInfo> BadUrls = new ConcurrentBag<UrlInfo>();
// timer fires every 50ms, whereupon a new args object is created
// and the timer callback spawns a new task; an autoEvent would
// reset the timer and dispose of it when the queue was empty
void SpawnNewUrlTask(){
// if queue is empty then reset the timer
// otherwise:
TestArgs args = {
myCollection = BadUrls,
currentUrl = getNextUrl() // take an item from the queue
};
Task.Factory.StartNew( asyncWebRequestAndConcurrentCollectionUpdater, args);
}
public async Task asyncWebRequestAndConcurrentCollectionUpdater(TestArgs args)
{
//make the async web request
// add the url to the bad collection if appropriate.
}
最佳答案
这种方法看起来不错,但是您显示的特定代码存在一些问题。
但是在此之前,评论中已经提出了建议,即“任务并行性”是可行的方法。我认为这是误导的。有一个常见的误解,即如果您想并行进行大量工作,则必然需要大量线程。仅当工作受计算限制时,这才是正确的。但是您正在做的工作将受到IO的约束-此代码将花费其大部分时间等待响应。它将执行很少的计算。因此,在实践中,即使仅使用一个线程,您最初的每秒20个请求的目标似乎也不会导致单个CPU内核大汗淋漓的工作量。
简而言之,单个线程可以处理非常高级别的并发IO。如果您需要并行执行代码,则只需要多个线程,而在这里似乎不太可能,因为在此特定工作中CPU的工作量很少。
(这种误解早于await
和async
数年。实际上,它早于TPL-请参见http://www.interact-sw.co.uk/iangblog/2004/09/23/threadless以了解.NET 1.1时代的插图,该插图说明了如何使用少量线程处理成千上万个并发请求。由于这些基本原理至今仍然适用,因为Windows网络IO基本上仍以相同的方式工作。)
并不是说在这里使用多个线程有什么特别的错误,我只是指出这有点让人分心。
无论如何,回到您的代码。这行是有问题的:
Task.Factory.StartNew( asyncWebRequestAndConcurrentCollectionUpdater, args);
StartNew
重载要求第一个参数是
Action
,
Action<object>
,
Func<TResult>
或
Func<object,TResult>
。换句话说,它必须是不带任何参数或接受
object
类型的单个参数(并且可能会或可能不会返回值)的方法。您的'asyncWebRequestAndConcurrentCollectionUpdater'采用
TestArgs
类型的参数。
Task.Factory.StartNew(() => asyncWebRequestAndConcurrentCollectionUpdater(args));
)真正的问题是您正在做的事情有点奇怪:您正在使用
Task.StartNew
调用已返回
Task
的方法。
Task.StartNew
是一种采用同步方法(即不返回
Task
的方法)并以非阻塞方式运行它的便捷方法。 (它将在线程池上运行。)但是,如果您已经有一个已经返回
Task
的方法,那么您实际上并不需要使用
Task.StartNew
。如果我们看一下
Task.StartNew
返回的结果(一旦您解决了编译错误),就会变得更加奇怪:
Task<Task> t = Task.Factory.StartNew(
() => asyncWebRequestAndConcurrentCollectionUpdater(args));
Task<Task>
揭示了正在发生的事情。您已经决定使用一种通常用于使非异步方法异步的机制来包装已经异步的方法。因此,您现在有了一个产生
Task
的
Task
。
StartNew
返回的任务完成,则不一定要完成基础工作:
t.Wait(); // doesn't wait for asyncWebRequestAndConcurrentCollectionUpdater to finish!
asyncWebRequestAndConcurrentCollectionUpdater
返回
Task
。并且由于
asyncWebRequestAndConcurrentCollectionUpdater
已经是一个异步方法,它将立即或多或少地返回一个任务。 (具体来说,它将在执行不立即完成的
await
时返回任务。)
t.Result.Wait();
t.Unwrap().Wait();
Task
,然后等待。这可能与这个简单得多的代码没有什么有用的区别:
Task t = asyncWebRequestAndConcurrentCollectionUpdater("foo");
... maybe queue up some other tasks ...
t.Wait();
async
之后继续
await
方法时,它在与最初执行
await
相同的上下文中这样做。例如,如果您在WPF应用中,并且在UI线程上使用
await
,则当代码继续执行时,它将在UI线程上进行操作。 (您可以使用
ConfigureAwait
禁用此功能。)
Task.Factory.StartNew
启动异步任务可能很有用,因为它使您可以转义原始上下文。但是,您的工作变得更加艰难-跟踪任务以完成任务会更加复杂。通过在
ConfigureAwait
方法中使用
async
,您可能已经能够实现相同的效果。
async
方法从队列中挑选一个URL,发出请求,检查响应,并在必要时将一个条目添加到错误的url集合中,这似乎是完全合理的。从计时器开始的事情似乎也很合理-这将限制尝试连接的速率,而不会因响应缓慢而陷入困境(例如,如果大量请求最终试图与离线服务器通信)。如果遇到某种病理情况,最终导致连续出现成千上万个URL都指向无响应的服务器,则可能有必要为运行中的最大请求数设置上限。 (在相关说明中,您需要确保使用的HTTP API不会达到每个客户端连接的限制-最终可能会限制有效的吞吐量。)
Task.Factory.StartNew
启动,请记住:最后,您需要进行额外的包装,因此您需要执行
myTask.Unwrap().ContinueWith(...)
之类的操作才能正确处理它。
关于c# - 异步任务的许多实例可以共享对并发集合的引用,并在C#中向其中并发添加项目吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18059904/
编辑:我似乎问错了这个问题。 我正在尝试寻找一种方法来查询一个集合是否在另一个集合中可用。例如: SELECT * FROM something WHERE (1, 3) IN (1, 2, 3, 4
这两种方法似乎 produce the same results ,但我一直很难真正说服人们第二种方法有效,因为它显然并不为人所知。 // Create some data var foo = { '
我一直在学习Kotlin,并且遇到过Collections API。在Kotlin之前,我一直在学习Java,并且我知道Java中有很多不同类型的Collections API。例如,我们使用List
为什么我会得到不同的行为: Collection col2 = new ArrayList(col); 集合 col2 = new ArrayList(); col2.addAll(col) 我正在与
所以我有一个代表专辑信息的 JSON 对象。给定“function updateRecords(id, prop, value)”我希望能够更新每个条目。正确的完成代码如下。 我得到了指示,粗体部分,
我想存储一个对象集合,这些对象根据它们所代表的值进行键控。这些键可以重复。例如: [4] => Bob [5] => Mary [5] => Sue [9] => Steve [10] =>
在检查 ArrayList API 时,我注意到一些看起来很奇怪的东西。 确实,这里是 ArrayList 构造函数实现,其中 Collection 作为参数传递: public ArrayList(
我正在为 API 编写一个 swagger 定义文件。 API 是用于 GET 请求的 /path/to/my/api: get: summary: My Custom API d
我知道scala.collection包中有两个非常有用的对象,可以帮助我们实现这个目标: JavaConverters(如果我想明确说明并准确说明我要转换的内容) JavaConversions(如
我已经阅读了无数其他帖子,但似乎无法弄清楚发生了什么,所以是时候寻求帮助了。 我正在尝试将包含集合的域实体映射到也包含集合的 dtos。 这是一个原始示例; (我提前为代码墙道歉,我尽量保持简短):
我正在创建一个具有 ArrayList 的类,因此当我调用构造函数时,它会初始化该数组: public class ElementsList { private ArrayList list;
我正在阅读事件指南和指南的开头,它说: You can also add an event listener to any element in the this.$ collection using
我是 Python 新手,想知道如何使用键在字典中存储不同数据类型的列表 例如 - {[Key1,int1,int1,String1] , [Key2,int2,int2,String2], [Key
int[] mylist = { 2, 4, 5 }; IEnumerable list1 = mylist; list1.ToList().Add(1); // why 1 does not get
我在 UI 表单中的每一行之后将以下内容添加到 HashMap 集合中 声明 Map> map = new HashMap>(); List valSetOne = new ArrayList();
我正在开发我的第一个 Java 项目,我有一个问题。问题应该很简单(虽然代码不是那么短,但没有理由被吓倒:))。我创建了一个基本的角色扮演游戏,并且有一个定义每个角色的抽象类“Character”。在
我正在开发一款应用程序,可以为用户收集推文、Facebook 状态和 Facebook 照片。目前,用户确切地设定了他们希望这种收获发生的时间和时间,并且蜘蛛会在此期间拉取数据。 when 和 to
有谁知道在 C# 中是否有与 Java 的 Set 集合等效的好方法?我知道您可以通过填充但忽略值来使用 Dictionary 或 HashTable 在某种程度上模仿集合,但这不是一种非常优雅的方式
EXISTS 该函数返回 集合中第一个元素的索引,如果集合为空,返回NULLNULLNULL Collecti
RDF集合是通过属性 rdf:parseType="Collection" 来描述仅包含指定成员的组 rdf:parseType="Collection" 属
我是一名优秀的程序员,十分优秀!