除了调用thread.Join()之外,如何等待线程完成运行? [英] How can I wait for a thread to finish running other than by calling thread.Join()?

查看:154
本文介绍了除了调用thread.Join()之外,如何等待线程完成运行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在一个项目中,该方法是从库中可用的应用程序中调用方法的。

I am working on a project where the methods are called from the an application which is available with the library.

我的按钮单击事件中包含以下代码:

I have the below code in my button click event:

Thread thread = new Thread(new ThreadStart(AddPics));
thread.Priority = ThreadPriority.Highest;
thread.Start();
execute();

但是在运行示例时,执行点始终移至执行位置。如何使程序首先执行 AddPics 方法。我已经尝试过 thread.Join()并成功了,但是我想知道是否还有其他方法可以实现这一目标。

But while running the sample always the execution point moves to the execute. How to make the program to execute the AddPics method first. I have tried thread.Join() and it worked, but I want to know if there is any other way to achieve this.

推荐答案

您可以使用 Join AutoResetEvent 等待添加图片线程修饰符,但是您不应该使用答案中稍后解释的任何一种方法。

You can use Join or AutoResetEvent to wait until add picture thread finishes, But you should not use either as explained later on the answer.

您可以通过使用<$获得相同的结果c $ c> AutoResetEvent 代替 Join ;它允许您设置阻止通知,因此请在调用 execute()方法之前进行阻止,并且仅在 AddPics 时继续进行线程完成其工作:

You can achieve the same results by using AutoResetEvent as alternative to Join; it allows you to setup a blocking-notification, so block before calling the execute() method and only proceed when AddPics thread finishes its job:

private AutoResetEvent _finishAddPicsNotifier = new AutoResetEvent(false);

private void OnMyButton_Click(object sender, EventArgs e)
{
    //.....
    new Thread(AddPics)
    {
        Priority = ThreadPriority.Highest,
        IsBackground = true, //will explain later
    }.Start();

    _finishAddPicsNotifier.WaitOne();//this will block until receive a signal to proceed
    execute();//this method will only be called after the AddPics method finished
    /.....
}

private void AddPics()
{
    try{
        //.......
    }
    finally{
        _finishAddPicsNotifier.Set();//when finished adding the pictures, allow the waiting method to proceed
    }
}

注意:设置 IsBackground = true 表示该线程是后台线程,因此不会阻止应用程序终止。在此处中了解更多信息。

Note: Set IsBackground = true to indicates that thread is a background thread so it will not prevent the application from terminating. read more about background thread here.

问题:


  • 由于您使用的是单击按钮以运行该线程,则应添加某种机制以防止多次单击以多次运行该代码。

  • 在调用<$时,您还将阻塞UI线程c $ c> Join()或 _finishAddPicsNotifier.WaitOne()

  • Since you are using a button click to run the thread, you should add some mechanism to prevent multi-clicks at the same time to run the code multiple time.
  • You are also blocking the UI thread when call Join() or _finishAddPicsNotifier.WaitOne().

要解决所有这些问题,一个好的设计是定义一个方法 OnFinishAddingPictures ,并在添加完图像后立即调用它,在此新方法调用 execute()中,还应该从按钮单击中删除先前的 execute()调用:

To fix all of that, a good design is to define a method OnFinishAddingPictures and call it whenever finish adding images, inside this new method call execute(), you should also remove the previous execute() call from button click:

private readonly object _oneAddPicturesLocker = new object();

private void OnMyButton_Click(object sender, EventArgs e)
{
    //.....
    new Thread(AddPics)
    {
        Priority = ThreadPriority.Highest,
        IsBackground = true,
    }.Start();
}

private void AddPics()
{
    if (Monitor.TryEnter(_oneAddPicturesLocker))
    {
        //we only can proceed if no other AddPics are running.
        try
        {
            //.....

            OnFinishAddingPictures();
        }
        finally
        {
            Monitor.Exit(_oneAddPicturesLocker);
        }
    }
}

private void OnFinishAddingPictures()
{
    execute();
}

注意:


  • 我们使用这种机制摆脱了阻塞。

  • 我们确定只有一个调用 AddPics 会立即执行。

  • 始终记得检查 InvokeRequired 并使用 control.Invoke(/*..*/)每当通过不是UI线程的线程访问表单或控件方法和属性时。

  • We get rid of the blocking using this mechanism.
  • We are sure One and Only one call to the AddPics are executed at a moment.
  • Always remember to check InvokeRequired and use control.Invoke(/*..*/) whenever accessing form or control methods and properties from a thread that is not the UI thread.

这篇关于除了调用thread.Join()之外,如何等待线程完成运行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆