从C#中的多个异步方法(即线程)增加值类型

Miq*_*uel 5 c# multithreading asynchronous async-await

我需要从C#中的多个线程(异步方法)中增加一个计数器。

  • 我无法传递ref参数,因为它是一个异步方法
  • 我不能只是更新值(或锁定它),因为它是一个值类型
  • 我无法使用互锁,因为我无法在异步方法中将引用添加到计数器

所以我唯一想做的就是做一个像a这样的愚蠢的东西,List<int>然后把我int放在那里,以便线程可以锁定List并更新值。

我希望这是一个已知的用例,并且有更优雅的方法吗?

这是一个小示例,不用担心语法问题:

public void DoStuff()
{
    int counter;
    var tasks = new List<Task>()
    for(int i = 0; i < 10; i++)
    {
        tasks.Add(AsyncMethod(<SOMETHING>));
    }
    Task.WaitAll(tasks);
    Console.WriteLine("Total: {0}", counter);
 }

 public async Task AsyncMethod(<SOMETHING>)
 {
     // Lock if needed by <SOMETHING>
     <SOMETHING>+=20;
 }
Run Code Online (Sandbox Code Playgroud)

我需要创建一个带有int字段的类,还是C#提供一些现成的东西?我并没有为此而烦恼,只是想事后想知道是否有更好的方法。谢谢!

对于未来的访问者:共识似乎是创建一个自定义类,例如class IntHolder { public int Value {get;set;}}可以通过引用传递并锁定(或使用Interlocked on)的类。

非常感谢!

Yac*_*sad 5

您可以lock在任何对象上使用,而不仅仅是要使用的对象。

例如:

object locking_object = new object();
Run Code Online (Sandbox Code Playgroud)

这将创建一个仅用于锁定的对象。

然后,当您想增加值时:

lock(locking_object)
{
    integer++;
}
Run Code Online (Sandbox Code Playgroud)

根据评论更新:

创建一个类来保存整数值,如下所示:

class IntHolder
{
    public int Value;
}
Run Code Online (Sandbox Code Playgroud)

您可以使用Interlocked该类执行以下操作:

Interlocked.Increment(ref int_holder.Value);
Run Code Online (Sandbox Code Playgroud)

您传递给方法int_holder的类型变量的名称在哪里IntHolder

  • @Miquel您显然需要能够从所有线程访问`int`。通过使其成为所有人员都可以访问的类的成员,或者将其包装为“ IntHolder”类,然后将对类实例的引用传递给所有线程。 (2认同)
  • 我猜Yorye Nathan在谈论定制课程。就像这个`IntHolder {public int Value;} (2认同)