【问题标题】:Execute a statement after thread gets over线程结束后执行语句
【发布时间】:2009-03-18 08:15:48
【问题描述】:

我有一个函数,我在 c#.net 中使用了一个线程。

我在该线程的下一行有另一个函数。但是这个函数只能在线程执行完毕后调用。

我该怎么做?

例子..

Somefunction()
{
    // thread        //(thread started)
    add()            (another function but need to be executed only tha above thread gets over)
}

【问题讨论】:

  • 我相信您想要的是在后台线程工作时继续执行主线程,但在完成后执行回调函数,对吧?

标签: c# .net multithreading


【解决方案1】:

使用 BackgroundWorker 并将函数调用包含在 worker 完成的事件处理程序中。

var worker = new BackgroundWorker();
_worker.DoWork += delegate { DoStuff(); };    
_worker.RunWorkerCompleted += worker_RunWorkerCompleted;
_worker.RunWorkerAsync();


[...]

private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
   /// Do post-thread stuff
}

【讨论】:

    【解决方案2】:

    使用Thread.Join 阻塞当前线程,直到指定线程完成执行。

    【讨论】:

      【解决方案3】:

      如果您希望执行是单线程的,为什么要启动一个单独的线程?

      【讨论】:

      • 这是在后台启动操作的常见示例,同时执行其他操作,然后等待该后台操作完成后再继续。
      • 有道理,但这不是 OP 所要求的
      • 我想是的,他说他启动了一个线程,然后在该线程完成后运行其他东西。
      • 好吧,他可能会启动第二个线程来做一些后台处理,现在想确保在执行 add() 调用之前它已经结束。
      • @CK:我认为@Dave 在这一点上是正确的。这个问题对我来说听起来确实很特别,但我认为它的意思是一样的。
      【解决方案4】:

      “在线程被执行之后”,你的意思是它必须启动吗?或者它必须完成

      如果您的意思是完成,那么您通常会 Join() 线程 - 但没有意义 Join()ing 您之前在行中盯着的线程(只需直接执行代码)。另一种方法是在线程方法的末尾使用“回调”。

      如果您的意思是开始,那么您可以执行以下操作:

      object lockObj = new object();
      lock(lockObj) {
          ThreadPool.QueueUserWorkItem(delegate {
              lock(lockObj) {
                  Monitor.Pulse(lockObj);
              }
              // do things (we're on the second thread...)
          });
          Monitor.Wait(lockObj);
      }
      // thread has definitely started here
      

      【讨论】:

        【解决方案5】:

        例如,您可以使用 ManualResetEvent。 当你在另一个线程上开始处理时,你调用了 reset 方法。 当另一个线程上的处理完成时,您调用 set. 那么,必须在“主线程”上执行的方法,需要等到ManualResetEvent设置后才能执行。

        有关更多信息,您可以查看 MSDN 上的the ManualResetEvent

        【讨论】:

          【解决方案6】:

          如果 add() 是线程安全的,只需在传递给创建线程的函数末尾调用它即可。

          【讨论】:

            【解决方案7】:

            您可以尝试以下方法,它可能不适用于您的场景:鉴于您提供的详细信息,我无法判断:

            首先创建一个委托:

            public delegate int MyThreadSignature(Something arg);
            

            然后使用 Begin/End Invoke 模式:

            var thread = new MyThreadSignature(WorkerMethod);
            thread.BeginInvoke(theArg, 
                               MyThreadEnded, /*Method to call when done*/, 
                               thread /*AsyncState*/);
            

            创建 MyThreadEnded 方法:

            void MyThreadEnded(IAsyncResult result)
            {
                var thread = (MyThreadSignature)result.AsyncState;
                var result = thread.EndInvoke(result);
                // Call your next worker here.
            }
            

            调用方法必须具有示例中的签名:Name(IAsyncResult result)。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2016-07-15
              • 1970-01-01
              • 1970-01-01
              • 2018-04-27
              • 1970-01-01
              • 1970-01-01
              • 2017-08-27
              • 1970-01-01
              相关资源
              最近更新 更多