【问题标题】:Pass delegate to Task将委托传递给任务
【发布时间】:2019-08-22 15:23:42
【问题描述】:

我想以某种方式将委托传递给 Task,它必须在请求时在该任务内的变量 (AutoResetEvent) 上执行一些代码。下面是伪代码:

var task = Task.Run(() => DoSth()); + delegate somehow

public async Task DoSth()
{
   public static AutoResetEvent waitEvent = new AutoResetEvent(true);
   while(true)
   {
       ...
       waitEvent.WaitOne(seconds * 1000);
   {
}

这个代表要做的是:

waitEvent.Set();

因为我不想等待 60 秒。

并且在某些时候告诉任务运行委托代码。

【问题讨论】:

  • 将线程原语(如 AutoResetEvent)与任务编程模型混合不是一个好主意...
  • 不清楚您要做什么。您能否更新您的问题以解释您实际尝试解决的问题?很有可能使用比传递委托更好的模式,例如使用 CancellationToken 或传递任务并等待 Task.WhenAny()

标签: c# multithreading


【解决方案1】:

您不应该开始一个任务,然后阻止等待其他事情。这将导致 ThreadPool 遭受一个无用的线程,最终可能导致 ThreadStarvation。

您应该启动一个新的专用线程并使用共享变量来触发您的工作。

new Thread(DoSth).Start();

private readonly object protect = new object();

public async Task DoSth()
{
   public static AutoResetEvent waitEvent = new AutoResetEvent(true);
   while(true)
   {
       bool triggered = false;
       lock(protect)
       {
           Monitor.Wait(protect, seconds * 1000);
           triggered = shouldWork;
           shouldWork = false;
       }

       if(triggered) 
           Work();
  }
}

public void Trigger()
{
    lock(protect)
    {
        shouldwork = true;
        Monitor.Pulse(protect);//will end the wait on the other thread
    }
}

【讨论】:

  • 我有很多线程/任务,这就是为什么我不能使用一个共享变量。尽管如此,我们将失去对该对象的引用。
猜你喜欢
  • 1970-01-01
  • 2018-05-07
  • 2012-03-19
  • 1970-01-01
  • 2012-07-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多