C# 线程终止时调用方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1163992/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 09:44:33  来源:igfitidea点击:

Calling a method when thread terminates

c#multithreadingasynchronousmethods

提问by RaYell

I have a form that starts a thread. Now I want the form to auto-close when this thread terminates.

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

The only solution I found so far is adding a timer to the form and check if thread is alive on every tick. But I want to know if there is a better way to do that?

到目前为止,我找到的唯一解决方案是在表单中添加一个计时器并检查线程是否在每个滴答声中都处于活动状态。但是我想知道是否有更好的方法来做到这一点?

Currently my code looks more less like this

目前我的代码看起来更不像这样

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
    }
}

采纳答案by Steve Gilham

The BackgroundWorker class exists for this sort of thread management to save you having to roll your own; it offers a RunWorkerCompleted event which you can just listen for.

BackgroundWorker 类存在于这种线程管理中,以节省您自己的工作;它提供了一个 RunWorkerCompleted 事件,您只需监听即可。

回答by Sam Harwell

Edit to make it call a helper method so it's cleaner.

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

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

...

private void OnWorkComplete()
{
    Close();
}

回答by Lloyd Powell

If you have a look at a BackgroundWorker, there is a RunWorkerCompleted event that is called when the worker completes.

如果您看一下 BackgroundWorker,就会发现一个 RunWorkerCompleted 事件会在工作器完成时调用。

For more info on BackgroundWorkers Click Here

有关 BackgroundWorkers 的更多信息,请单击此处

Or

或者

You could add a call to a complete function from the Thread once it has finished, and invoke it.

一旦完成,您可以从线程添加对完整函数的调用,并调用它。

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

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

回答by Adriaan Stander

Have a look at delegates, IAsyncResult, BeginInvoke and AsyncCallback

查看委托、IAsyncResult、BeginInvoke 和 AsyncCallback

回答by Philippe Leybaert

At the end of your thread method, you can call Close() using the Invoke() method (because most WinForms methods should be called from the UI thread):

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

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

回答by Pavel Tupitsyn

Solution for arbitrary thread (e.g. started by some other code), using UnmanagedThreadUtilspackage:

使用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.");
}