线程终止时调用方法

时间:2009-07-22 09:02:47

标签: c# multithreading asynchronous methods

我有一个启动线程的表单。现在我希望表单在该线程终止时自动关闭。

我到目前为止找到的唯一解决方案是在表单中添加一个计时器,并检查每个tick上是否存在线程。但我想知道是否有更好的方法来做到这一点?

目前我的代码看起来更像是

partial class SyncForm : Form {
    Thread tr;

    public SyncForm()
    {
        InitializeComponent();
    }

    void SyncForm_Load(object sender, EventArgs e)
    {
        thread = new Thread(new ThreadStart(Synchronize));
        thread.IsBackground = true;
        thread.Start();
        threadTimer.Start();
    }

    void threadTimer_Tick(object sender, EventArgs e)
    {
        if (!thread.IsAlive)
        {
            Close();
        }
    }

    void Synchronize()
    {
        // code here
    }
}

6 个答案:

答案 0 :(得分:11)

对于这种线程管理,存在BackgroundWorker类,以节省您必须自己滚动;它提供了一个RunWorkerCompleted事件,你可以只听。

答案 1 :(得分:6)

编辑以使其调用辅助方法,使其更清晰。

thread = new Thread(() => { Synchronize(); OnWorkComplete(); });

...

private void OnWorkComplete()
{
    Close();
}

答案 2 :(得分:6)

如果您查看BackgroundWorker,则会在工作人员完成时调用RunWorkerCompleted事件。

有关BackgroundWorkers Click Here

的更多信息

完成后,您可以从线程中添加对完整函数的调用,然后调用它。

void Synchronize()
{
    //DoWork();
    //FinishedWork();
}

void FinishedWork()
{
if (InvokeRequired == true)
  {
  //Invoke
  }
else
  {
  //Close
  }
}

答案 3 :(得分:1)

查看委托,IAsyncResult,BeginInvoke和AsyncCallback

答案 4 :(得分:1)

在线程方法结束时,可以使用Invoke()方法调用Close()(因为大多数WinForms方法应该从UI线程调用):

public void Synchronize()
{
   Invoke(new MethodInvoker(Close));
}

答案 5 :(得分:0)

使用UnmanagedThreadUtils程序包解决任意线程的问题(例如,由其他代码启动):

// Use static field to make sure that delegate is alive.
private static readonly UnmanagedThread.ThreadExitCallback ThreadExitCallbackDelegate = OnThreadExit;

public static void Main()
{
    var threadExitCallbackDelegatePtr = Marshal.GetFunctionPointerForDelegate(ThreadExitCallbackDelegate);
    var callbackId = UnmanagedThread.SetThreadExitCallback(threadExitCallbackDelegatePtr);

    for (var i = 1; i <= ThreadCount; i++)
    {
        var threadLocalVal = i;

        var thread = new Thread(_ =>
        {
            Console.WriteLine($"Managed thread #{threadLocalVal} started.");
            UnmanagedThread.EnableCurrentThreadExitEvent(callbackId, new IntPtr(threadLocalVal));
        });

        thread.Start();
    }

    UnmanagedThread.RemoveThreadExitCallback(callbackId);
}

private static void OnThreadExit(IntPtr data)
{
    Console.WriteLine($"Unmanaged thread #{data.ToInt64()} is exiting.");
}