【问题标题】:A queued function (void) for multiple threads in C#C#中多个线程的排队函数(void)
【发布时间】:2021-12-31 06:49:27
【问题描述】:

我的 C# 程序中有多个线程。现在他们在运行时偶尔调用一个特定的函数。现在我想确保他们永远不会同时执行那个特定的函数(因为它会导致我的程序出现一些异常),对函数的一次调用必须在下一次调用开始之前完成。 (很像一个队列)。

有可能做到这一点吗? (不必须成为函数)。

如果有些人看不懂,这里是一张图表:

【问题讨论】:

  • 只需将您的函数调用包装到 lock 语句 (docs.microsoft.com/en-us/dotnet/csharp/language-reference/…) 中。或者只是在函数内部添加一个lock
  • 我会实施并通知您!
  • 非常感谢,它有效! (您可以将其写为答案,以便我将其标记为正确的答案)。
  • 你可能会觉得这个问题很有趣:What does a lock statement do under the hood?
  • 了解更多关于您的程序会很有趣,因为 Microsoft 的反应式框架可能是一个很好的解决方案,具体取决于您的架构。

标签: c# multithreading


【解决方案1】:

您可以使用lock 关键字来防止并行执行代码片段。 只需将函数的调用包装到 lock 语句中或在函数本身中添加一个锁。

class MyClass
{
    private object lockObj = new();
    
    public void MyFunction()
    {
        lock(lockObj)
        {
            //code goes here
        }
    }
}

    //usage
    void Test()
    {
        var myClass = new MyClass();
        var thread1 = new Thread(ThreadFunc);
        var thread2 = new Thread(ThreadFunc);
        
        thread1.Start(myClass);
        thread2.Start(myClass);
    }
    
    public static void ThreadFunc(object myClassObj)
    {
        var myClass = (MyClass)myClassObj;
        myClass.MyFunction();
    }

请注意此处的 lockObj 对象。为了实现您想要的行为,您应该在lock 语句中使用完全相同的lockObj 值。所以,以下是错误的

//WRONG, do NOT DO this
    var myClass1 = new MyClass();
    var myClass2 = new MyClass();
    var thread1 = new Thread(ThreadFunc);
    var thread2 = new Thread(ThreadFunc);

    thread1.Start(myClass1);
    thread2.Start(myClass2);

这里我们有两个MyClass的独立实例,所以每个实例都有自己的lockObj值,因此这些实例不会相互锁定,所以myClass1.MyFunction()和并行执行myClass2.MyFunction() 在这里是允许的。

【讨论】:

    猜你喜欢
    • 2011-06-09
    • 2018-03-09
    • 2010-10-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多