Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 函数,该函数始终返回序列中的下一个整数_.net_Vb.net_Caching - Fatal编程技术网

.net 函数,该函数始终返回序列中的下一个整数

.net 函数,该函数始终返回序列中的下一个整数,.net,vb.net,caching,.net,Vb.net,Caching,我需要创建一个函数来获取1到60序列中的下一个整数。每次调用函数时,我都需要它从上一个值开始递增,并返回下一个数字作为结果。它也不能在两个连续调用中返回相同的整数。当计数达到60时,序列需要重置回1。我希望函数没有参数 我创建了一个函数,它使用缓存来存储返回的最后一个值,但我担心对该函数的并发调用可能无法像我预期的那样工作,2次调用可能会得到相同的整数 缓存阻塞是在这个实例中使用的正确方法,还是我没有考虑其他方法 另外,使用.NET3.5时遇到了问题,这是一个web应用程序 我刚刚使用Sync

我需要创建一个函数来获取1到60序列中的下一个整数。每次调用函数时,我都需要它从上一个值开始递增,并返回下一个数字作为结果。它也不能在两个连续调用中返回相同的整数。当计数达到60时,序列需要重置回1。我希望函数没有参数

我创建了一个函数,它使用缓存来存储返回的最后一个值,但我担心对该函数的并发调用可能无法像我预期的那样工作,2次调用可能会得到相同的整数

缓存阻塞是在这个实例中使用的正确方法,还是我没有考虑其他方法

另外,使用.NET3.5时遇到了问题,这是一个web应用程序


我刚刚使用SyncLock编写了这个函数。有什么我看不到的明显问题吗?我正在使用缓存保存最后返回的值

   Private Shared Function GetNextNumber() As Integer
        Dim o As Integer
        Dim r As Integer

        If Not Cache("NextNumber") Is Nothing Then
            o = DirectCast(Cache("NextNumber"), Integer)
        Else
            Cache.Insert("NextNumber", 1, Nothing, Nothing, Nothing, Caching.CacheItemPriority.NotRemovable, Nothing)
        End If

        Dim lock As New Object

        SyncLock lock
            If o = 60 Then
                r = 1
            Else
                r = o + 1
            End If
            Cache.Insert("NextNumber", r, Nothing, Nothing, Nothing, Caching.CacheItemPriority.NotRemovable, Nothing)
        End SyncLock

        Return r
    End Function

在java中,我会使用原子整数。。。找到以下端口:

Java代码片段:

public class Sequence {
   private final AtomicInteger counter;
   Sequence(int max) {
     counter = new AtomicInteger(0); 
     this.max = max);
   }
   public int next() {
     counter.compareAndSet(max,0);
     return counter.getAndIncrement();
   }
}

听起来您正在实现一个
IEnumerator
。这是一个开始的好地方。关于螺纹安全,该条款规定:

枚举器对集合没有独占访问权;因此,通过集合枚举本质上不是线程安全的过程。即使在同步集合时,其他线程仍可以修改该集合,这会导致枚举数引发异常。为了保证枚举期间的线程安全,您可以在整个枚举期间锁定集合,也可以捕获由其他线程所做的更改导致的异常

有关使用锁定创建线程安全的IEnumerator的示例,请参阅

现在,您的线程安全性是否要求每个线程使用自己的
IEnumerator
或共享一个?我认为引用的CodeProject文章假设的是前者。后者可能很困难,因为
MoveNext
Current
在设计上是独立的操作。因此,在原子上锁定两者听起来像是一个设计挑战


幸运的是,Jon Skeet似乎有:)

ASP.net缓存是线程安全的,但有可能两个线程同时访问同一对象

我建议看一下“ConcurrentQueue(Of T)类”

并发队列将阻止调用,直到原始调用完成。此外,因为每次删除一个项目时,它都是一个堆栈,所以只需将其推回到堆栈中,形成一个顺序循环

即:

端模块

这就是我在3.5中的做法:

Module Module1

Private _Stack As New Queue(Of Integer)

Sub main()

    For i As Integer = 1 To 60
        _Stack.Enqueue(i)
    Next

    Do While True
        Debug.WriteLine(GetNext())
    Loop

End Sub

Private Function GetNext() As Nullable(Of Integer)
    Dim result As Integer

    SyncLock _Stack

        result = _Stack.Dequeue()

        _Stack.Enqueue(result)

    End SyncLock

    Return result

End Function

终端模块

这是共享功能吗?可以从多个线程同时调用它。我可以从您的担忧中推断出这一点,但您没有说。
属性解决了这个问题。它可能最终被多个线程调用。我现在正在研究
属性。根据MSDN上的定义判断,我认为ThreadStatic不是我们要寻找的:标记为ThreadStaticAttribute的静态字段在线程之间不共享。每个执行线程都有一个单独的字段实例,并独立地设置和获取该字段的值。如果在不同的线程上访问该字段,它将包含不同的值。我是否误解了这个问题?我愿意接受任何有效的解决方案。该函数将在我们的应用程序中全局使用,因此无论是单线程还是多线程,它都需要可靠。如果这有帮助的话,它是一个在线应用程序。@NinjaBomb:听起来你想要一个线程安全的单例对象,那么。每个线程没有单独的对象。那就是。。。如果Thread1请求一个数字,它将得到1。然后thread3请求,得到2。然后Thread1再次询问,它得到3。线程2请求,得到4。等等在这种情况下,推荐Jon Skeet博客中的链接帖子。唯一的区别是,当到达集合的末尾时,您不希望停止枚举。你想重置为1。抱歉,我刚刚编辑了这个问题,以注意我们在.Net 3.5上,所以我认为该类不可用。它不是…你可以使用普通队列(t)并将_Stack.Dequeue包装在SyncLock中SyncLock方法可能看起来像是一种方法。希望我今天可以测试它,并让您知道。到目前为止,在我们的测试中,synclock方法工作正常。
Module Module1

Private _Stack As New Queue(Of Integer)

Sub main()

    For i As Integer = 1 To 60
        _Stack.Enqueue(i)
    Next

    Do While True
        Debug.WriteLine(GetNext())
    Loop

End Sub

Private Function GetNext() As Nullable(Of Integer)
    Dim result As Integer

    SyncLock _Stack

        result = _Stack.Dequeue()

        _Stack.Enqueue(result)

    End SyncLock

    Return result

End Function