gpt4 book ai didi

c# - 除了调用 thread.Join() 之外,如何等待线程完成运行?

转载 作者:行者123 更新时间:2023-11-30 18:47:09 24 4
gpt4 key购买 nike

我正在从事一个项目,其中的方法是从库提供的应用程序调用的。

我的按钮点击事件中有以下代码:

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

但是在运行示例时,执行点总是移动到执行。如何让程序先执行AddPics方法。我试过 thread.Join() 并且它有效,但我想知道是否有任何其他方法可以实现此目的。

最佳答案

您可以使用 JoinAutoResetEvent 来等待添加图片线程完成,但您不应该使用其中任何一个,如稍后在答案中解释的那样。

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

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 以指示该线程是后台线程,因此它不会阻止应用程序终止。阅读有关后台线程的更多信息 here .

问题:

  • 由于您使用按钮单击来运行线程,因此您应该添加一些机制来防止同时多次单击以多次运行代码。
  • 调用 Join()_finishAddPicsNotifier.WaitOne() 时,您也会阻塞 UI 线程。

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

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 线程

关于c# - 除了调用 thread.Join() 之外,如何等待线程完成运行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6423380/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com