首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ISynchronizeInvoke调用与BeginInvoke

ISynchronizeInvoke调用与BeginInvoke
EN

Stack Overflow用户
提问于 2021-04-28 00:17:59
回答 2查看 234关注 0票数 1

我已经编写了自己的timer类,它是Windows多媒体定时器的包装器。

我将计时器类建模在.NET的System.Timers.Timer类上。

我很难理解为什么.NET的计时器在同步对象上调用BeginInvoke,而不是Invoke

代码语言:javascript
复制
if (this.SynchronizingObject != null && this.SynchronizingObject.InvokeRequired)
{
    this.SynchronizingObject.BeginInvoke(intervalElapsed, new object[]{this, elapsedEventArgs};
}
else
{
    intervalElapsed(this, elapsedEventArgs);
}

我的理解是,BeginInvoke最终应该通过调用EndInvoke来匹配。没有找到EndInvoke

  1. .NET的做法有什么“不对”吗?为什么BeginInvoke在这里会更好呢?
  2. 如果我在课堂上也使用BeginInvoke,这是否意味着我的类的计时器事件可以在以前的事件完成之前触发(重新进入问题)?这会不会挫败(某些)与同步对象同步的目的?
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2021-04-28 06:40:22

Invoke方法阻塞调用线程,直到完成所提供的委托的执行为止,由于各种原因,这可能需要很长时间。例如,委托可能包含阻塞调用,或者目标上下文可能暂时被阻塞,等等。在System.Timers.Timer类的情况下,调用线程总是一个ThreadPool线程,这是一个有限的资源池。阻塞ThreadPool线程是个坏主意,因为它很容易导致池的饱和,导致效率低下和响应能力降低。这就是为什么调用BeginInvoke更可取的原因,因为它只是调度委托的执行,而调度通常是一个相当快的操作。不需要调用EndInvoke

System.Timers.Timer.Elapsed事件在设计上是可重入的,如果它调用Invoke而不是BeginInvoke,它仍然是可重入的。这是因为事件是在线程池上触发的。作为比较,System.Windows.Forms.Timer.Tick事件不是重入者,因为它总是在同一个线程UI线程上触发。System.Timers.Timer.Elapsed事件的可重入性是不使用System.Timers.Timer类而使用异步循环的参数。您可以查看这个问题的例子:定期运行具有指定间隔的异步方法。。不使用该类的其他参数是事件处理程序燕子例外,以及该类不是线程安全的。线程安全类一般不会公开事件,因为事件是固有的非线程安全机制

票数 2
EN

Stack Overflow用户

发布于 2021-04-28 01:28:44

调用将阻塞当前线程和主线程。

而BeginInvoke只阻塞主线程。

你可以试试wpf。

MainWindow.xaml

代码语言:javascript
复制
<Window x:Class="WpfApp5.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfApp5"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
    </Window.Resources>
    <UniformGrid Columns="1">
        <TextBlock Text="{Binding TimeString}"/>
        <Button Content="Invoke" Click="Invoke_Button_Click"/>
        <Button Content="BeginInvoke" Click="BeginInvoke_Button_Click"/>
    </UniformGrid>
</Window>

MainWindow.xaml.cs

代码语言:javascript
复制
using System;
using System.ComponentModel;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;

namespace WpfApp5
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window, INotifyPropertyChanged
    {

        public event PropertyChangedEventHandler PropertyChanged;

        private string tmeString;
        public string TimeString
        {
            get { return this.tmeString; }
            set
            {
                this.tmeString = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(TimeString)));
            }
        }

        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
            Task.Run(() =>
            {
                while (true)
                {
                    TimeString = $"DateTimeNow : {DateTime.Now}";

                    Thread.Sleep(1000);
                }
            });
        }

        private void BeginInvoke_Button_Click(object sender, RoutedEventArgs e)
        {
            Dispatcher.BeginInvoke((Action)SomeWork, null);
            //break point here
            bool buttonClickEventEnd = true;
        }

        private void Invoke_Button_Click(object sender, RoutedEventArgs e)
        {
            Dispatcher.Invoke((Action)SomeWork, null);
            //break point here
            bool buttonClickEventEnd = true;
        }

        private void SomeWork()
        {
            Thread.Sleep(3 * 1000);
        }
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67292170

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档