- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我一直注意到对 WaitHandle.WaitAny 的调用会分配给它的 WaitHandle[] 的副本。从下面的链接或使用反射器可以看出:
相关代码为:
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
public static int WaitAny(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
{
if (waitHandles==null)
{
throw new ArgumentNullException("waitHandles");
}
if (MAX_WAITHANDLES < waitHandles.Length)
{
throw new NotSupportedException(Environment.GetResourceString("NotSupported_MaxWaitHandles"));
}
if (-1 > millisecondsTimeout)
{
throw new ArgumentOutOfRangeException("millisecondsTimeout", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegOrNegative1"));
}
WaitHandle[] internalWaitHandles = new WaitHandle[waitHandles.Length];
for (int i = 0; i < waitHandles.Length; i ++)
{
WaitHandle waitHandle = waitHandles[i];
if (waitHandle == null)
throw new ArgumentNullException(Environment.GetResourceString("ArgumentNull_ArrayElement"));
if (RemotingServices.IsTransparentProxy(waitHandle))
throw new InvalidOperationException(Environment.GetResourceString("InvalidOperation_WaitOnTransparentProxy"));
internalWaitHandles[i] = waitHandle;
}
#if _DEBUG
// make sure we do not use waitHandles any more.
waitHandles = null;
#endif
int ret = WaitMultiple(internalWaitHandles, millisecondsTimeout, exitContext, false /* waitany*/ );
for (int i = 0; i < internalWaitHandles.Length; i ++)
{
GC.KeepAlive (internalWaitHandles[i]);
}
if ((WAIT_ABANDONED <= ret) && (WAIT_ABANDONED+internalWaitHandles.Length > ret))
{
int mutexIndex = ret -WAIT_ABANDONED;
if(0 <= mutexIndex && mutexIndex < internalWaitHandles.Length)
{
throw new AbandonedMutexException(mutexIndex,internalWaitHandles[mutexIndex]);
}
else
{
throw new AbandonedMutexException();
}
}
else
return ret;
}
现在我的问题是为什么?这是否可以规避(即编写自己的 WaitHandle.WaitAny 副本)?也许为什么不呢?
这意味着我的系统中有很多不必要的内存分配。由于低级别的方式,我们将其与多个 WaitHandles 一起使用。
请留在主题上,不要提及任务并行库或类似库;)我们在这里讨论的是 GC 压力很重要的高性能场景。
最佳答案
WaitMultiple
需要能够指望 WaitHandle
没有被垃圾回收。如果发生这种情况,可能会由于内存损坏或某些类似的问题而导致访问冲突。
我们的想法是,您应该能够调用 WaitMultiple
并销毁一个或多个 WaitHandle
对象,而 WaitAny
不会失败。如果它不创建一个副本,这将是不可能的,并且调试那个特定场景会花费你一整天的时间。所以最重要的是,它是为了线程安全而完成的。
如果您查看底层 native 函数的文档,WaitForMultipleObjects ,有证据表明:行为被描述为未定义:
If one of these handles is closed while the wait is still pending, the function's behavior is undefined.
如下文所建议的,如果充分利用它的所有性能很重要,您可以确保不释放 WaitHandles,并对 WaitForMultipleObjects 进行 p/invoke 调用。您可以提供 WaitHandle.SafeWaitHandle
作为相关同步对象的句柄。
编辑:上面给出的答案是错误的。我不时回到这个问题,因为它困扰着我;我现在相信我有一个正确的答案。
这种元素传输的目的是对各个 WaitHandle
进行线程安全验证。如果开发人员要使用原始数组,则其元素之一可能会被覆盖,例如 null
值,这将导致底层 native 函数出现未定义的行为。通过将元素复制到内部数组中,我们可以检查每个元素,如果它为 null
或无效则抛出异常,然后存储它。我们知道内部数组的元素不能被替换。因此,为了您很久以前的目的,如果您不做一些奇怪的事情,例如将 null 或跨 AppDomain 元素放入您的 WaitHandle 数组,您就可以了。
关于c# - WaitHandle.WaitAny 每次调用时都会分配 WaitHandle[] 的副本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15367599/
当我使用 int event_idx = WaitHandle.WaitAny(ExportEvents.ToArray()); 如果事件在 WaitAny 函数调用之前处于信号状态,则 WaitAn
我有固定数量的“浏览器”,每个浏览器都不是线程安全的,因此必须在单个线程上使用。另一方面,我有一长串线程等待使用这些浏览器。我目前正在做的是有一个 AutoResetEvent 数组: public
我正在尝试编写一些代码来并行调用多个不同服务器的 Web 服务,因此 TPL 似乎是显而易见的选择。 我的 Web 服务调用中只有一个会返回我想要的结果,而其他所有调用都不会。我正在尝试找到一种有效地
我一直试图找到一种方法来异步检查以查看我使用videocapture拍摄的下一帧相机是否准备就绪。 我遇到了waitAny(),它被描述为“等待VideoCapture的就绪帧”。 在OpenCV文档
我在数组中有一系列任务。如果 Task 是“Good”,它会返回一个字符串。如果它是“坏”:它返回一个空值。 我希望能够并行运行所有任务,一旦第一个返回“好”,然后取消其他任务并获得“好”结果。 我现
我刚刚开始探索 TPL 并有一个设计问题。 我的场景:我有一个 URL 列表,每个 URL 都引用一个图像。我希望并行下载每个图像。下载至少一个图像后,我想执行一种方法来对下载的图像执行某些操作。该方
我对 WaitAll 和 WaitAny 有点困惑。我试图获得异常,但是当我执行 WaitAll 时它返回异常但是当使用 WaitAny 时什么都不返回。必要的是,如果任何任务完成工作完成。他们的任何
我正在创建一个系统,该系统会生成大量辅助任务,并且在我的应用程序的某个位置,我正在执行 Task.WaitAny 以检索第一个完成的任务。 我关心的是我可以向 WaitAny 发送多少任务,我知道 W
我发现了一些使用 Task.WaitAny 条件的代码。 Task[] tasks = new Task[3]; tasks[0] = Task.Run(() => { Thread.Sleep(20
我正在使用 Task.WaitAny 并传入正在运行的任务数组。如果有多个任务同时完成,我想知道如何捕获所有已完成任务的索引。 例如,我正在检索完成如下任务的索引:` int i = Task.Wai
int WaitAny(Task[] tasks, int millisecondsTimeout); 上述方法是否在超时后取消任务?看起来没有,但 C# 70-483 考试引用书说这个重载版本取消了
编辑:我什至想为暂时的精神错乱辩护,甚至问这个问题,但当时它是有道理的(见下面的编辑 2)。 对于 .NET 3.5 项目,我有两种类型的资源(R1 和 R2)需要检查其可用性。每种资源类型在任何时候
在这段代码中,您总是会得到相同的结果。不知道为什么这些任务的ID是1,3,4。 如果您在 int index = Task.WaitAny(tasks); 处放置一个断点并等待 2 秒,您将获得良好的
如何在超过 64 个句柄上实现 waitAny? 我有一个简单的问题,我有很多线程一直工作到数据结束,当线程是数据结束时,然后向线程发送信号,告诉线程我正在为空闲线程运行这个 waitAny 并给他下
如果我没记错的话,JoinBlock是 TPL 数据流的“WaitAll”:当您有一个 T1 和一个 T2 时,它会构建一个 Tuple并将其传递给下一个 block 。 是否有一个“ChoiceBl
以下代码是主/工作模式的实现。 Ibcast 用于终止所有工作人员,因为我们不知道程序开始时问题的大小。 MPI_Waitany() 用于等待 Irecv 获取新数据和 Ibcast 终止程序。 问题
我一直注意到对 WaitHandle.WaitAny 的调用会分配给它的 WaitHandle[] 的副本。从下面的链接或使用反射器可以看出: http://reflector.webtropy.co
我知道我的目标可以通过使用 Task.WhenAny() 来实现,但如果可以避免,我不会处理异步等待,以防止死锁。我有以下代码: try { Task.WaitAny(this.Tasks.To
我有 3 个线程,两个“ worker ”和一个“经理”。 “工作人员”线程在 EventWaitHandle 上等待,“经理”线程将在增加其计数器后向 EventWaitHandle 发出信号。这些
我正在将 C++ API 代码移植到 .NET 并研究函数调用 WaitHandle.WaitAny 作为 WaitForMultipleObjects< 的替代品 但在使用 .NET4 进行调试时,
我是一名优秀的程序员,十分优秀!