• Почему сохраняются старые значения в потоке?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    Вы используете экземпляр BackgroundWorker, который живет на уровне класса.

    Всякий раз, когда вы нажимаете на кнопку, к экземпляру BackgroundWorker подключается новый обработчик события DoWork. Т.е. нажмете один раз на кнопку, будет один обработчик, нажмете два раза, то уже будет два обработчика, нажмете десять раз - будет десять обработчиков и все они будут работать. Это будет хорошо видно, когда обработчиков будет много, из-за рассинхронизации значение i будет меняться быстрее, хаотичней. Так что вывод переменной на уровень класса и присваивание ей нулевого значения - это не решение проблемы.

    В данном случае, можно либо всякий раз при нажатии на кнопку создавать новый экземпляр BackgroundWorker:

    private void button2_Click(object sender, EventArgs e) // запуск таймера класс BackgroundWorker
    {
      // создаем новый экземпляр BackgroundWorker
      bw = new BackgroundWorker();
      // остальной код
      key = true;
      // ...
    }

    Либо отключать обработчик, но для этого придется иметь ссылку на него (bw.DoWork -= ссылкаНаОбработчик). При таком варианте проще отказаться от анонимных функций и использовать обычные.

    Если интересно, то количество обработчиков события DoWork у экземпляра BackgroundWorker можно проверить так:

    EventHandlerList events = (EventHandlerList)typeof(Component).GetProperty
    (
      "Events", 
      BindingFlags.NonPublic | BindingFlags.Instance
    ).GetValue(bw, null);
    
    var k = typeof(BackgroundWorker).GetField
    (
      "doWorkKey", 
      BindingFlags.NonPublic | BindingFlags.Static
    ).GetValue(null);
    
    var handlers = events[k];
    
    Console.WriteLine
    (
      "Обработчиков {0}", 
      handlers.GetInvocationList().Length
    );
    Ответ написан
    1 комментарий
  • Почему сохраняются старые значения в потоке?

    DarkRaven
    @DarkRaven
    разработка программного обеспечения
    Я внес небольшие изменения:
    bool key;
    Timer time; /*вынес класс*/
    volatile int i; /*вынес i и пометил как volotile, но если у вас Intel и один поток, то это не обязательно*/
    
    BackgroundWorker bw = new BackgroundWorker();
    private void button2_Click(object sender, EventArgs e) // запуск таймера класс BackgroundWorker
    {

    У меня текст менялся - Таймер. Время: 1, Таймер. Время: 2 и т.д.

    Вопрос, у вас какой процессор?
    Представленный пример кода - это упрощенная версия? Если да, вы его проверяли?
    У вас только один поток меняет значение переменной i?
    Ответ написан
    3 комментария
  • Почему нет доступа к форме при использовании потока?

    AlekseyNemiro
    @AlekseyNemiro
    full-stack developer
    Как изменить textbox формы из другого класса?

    bw.DoWork += (o, eo) =>
    {
      for (;;)
      {
        i = time.Time(i);
        Thread.Sleep(1000);
        // https://msdn.microsoft.com/ru-ru/library/zyzhdc6b.aspx
        Invoke(new Action(() => {
          Text = "Таймер. Время: " + i;
        }));
      }
    };
    Ответ написан
    3 комментария
  • Как вызвать функцию в php?

    @almatalmat
    Я новичок в сфере программирование
    Можно.Смотрите
    <form action="drugoy_file.php" method="get">
        <input type="hidden" name="bb">
        <input type="submit">
    </form>

    <?
        //drugoy file
       if(isset($_GET['bb'])){
           tvoyafunctia();
       }
    ?>
    Ответ написан
    Комментировать
  • Как исправить ошибку в ajax?

    neovictor
    @neovictor
    Фрилансер
    Может в обработчике dispatch.php ошибка?
    Ответ написан
    8 комментариев
  • Как в Image программно указать картинку?

    JohnnyGat
    @JohnnyGat
    Стараюсь писать код, понятный человеку.
    Файл "App.xaml":
    <Application x:Class="WpfApplication1.App"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:local="clr-namespace:WpfApplication1"
                 StartupUri="MainWindow.xaml">
        <Application.Resources>
            <BitmapImage x:Key="MyImageSource" UriSource="H:\Temp\WpfApplication1\WpfApplication1\bin\Debug\icon1.png" />
        </Application.Resources>
    </Application>


    Файл "MainWindow.xaml":
    <Window x:Class="WpfApplication1.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:WpfApplication1"
            mc:Ignorable="d"
            Title="MainWindow" Height="350" Width="525">
        <Grid>
            <Image Name="Fast" Width="15" Height="15" HorizontalAlignment="Stretch" Margin="0,0,170,0" Source="{DynamicResource MyImageSource}"/>
            <Button Name="button" Content="Button" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="75" Click="button_Click"/>
        </Grid>
    </Window>


    Файл "MainWindow.xaml.cs":
    using System;
    using System.Windows;
    using System.Windows.Media.Imaging;
    
    namespace WpfApplication1
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private void button_Click(object sender, RoutedEventArgs e)
            {
                Application.Current.Resources["MyImageSource"] =
                    new BitmapImage(new Uri(@"H:\Temp\WpfApplication1\WpfApplication1\bin\Debug\icon2.png"));
            }
        }
    }


    По нажатию на кнопку происходит смена картинки на форме.
    Ответ написан
    1 комментарий
  • Как уведомить пользователя о том, что в данный момент происходит удаление?

    andrewpianykh
    @andrewpianykh
    Напрашивается:
    this.IsEnabled="False";

    Если операция удаления довольно продолжительная по времени, то стоило бы выполнять ее в другом потоке (не в "UI-потоке"):

    var bw = new BackgroundWorker();
    bw.DoWork += (o, eo) =>
    {
    	Directory.Delete("Путь каталога", true);
    };
    bw.RunWorkerCompleted += (o, eo) =>
    {
    	IsEnabled = true;
            Mouse.OverrideCursor = Cursors.Arrow;
    };
    
    IsEnabled = false;
    Mouse.OverrideCursor = Cursors.Wait;
    bw.RunWorkerAsync();
    Ответ написан
    3 комментария
  • Как вызвать функцию определяющую фокус для Window?

    andrewpianykh
    @andrewpianykh
    Можно передавать в конструктор Window2 ссылку на экземпляр Window1. Например, так:

    private readonly Window1 window1;
    
    public Window2(Window1 window1)
    {
    	InitializeComponent();
    	this.window1 = window1;
    }


    Создавайте экземпляр Window2 (если создание происходит в Window1):
    Window2 open = new Window2(this);

    И после этого задавайте фокус для окна window1

    window1.Focus();
    -----------
    Иначе, можно покопаться в коллекции всех окон приложения через свойство Application.Current.Windows
    Ответ написан
    1 комментарий
  • Как изменить Foreground MenuItem при наведении мыши?

    Частая ошибка

    <MenuItem Name="Setting" Header="Настройки">
                    <MenuItem.Style>
                        <Style TargetType="MenuItem" BasedOn="{StaticResource {x:Type MenuItem}}">
                            <Setter Property="Foreground" Value="Lime"></Setter>
                        </Style>
                    </MenuItem.Style>
                    <MenuItem Header="Свойства"/>
                    <MenuItem Header="О программе"/>
                    <MenuItem Header="Выход"/>
                </MenuItem>
    Ответ написан
    3 комментария
  • Как изменить задний фон дочерних MenuItem?

    lexxpavlov
    @lexxpavlov
    Программист, преподаватель
    Нужно переопределить шаблон элемента меню - просто добавить этот код в Window.Resources и всё, даже добавлять в <Menu> ничего не надо. "MenuItem.TopLevelHeaderTemplateKey" - стандартное название шаблона
    <ControlTemplate x:Key="{x:Static MenuItem.TopLevelHeaderTemplateKey}" TargetType="{x:Type MenuItem}">
        <Border Name="Border" >
            <Grid>
                <ContentPresenter Margin="6,3,6,3" ContentSource="Header" RecognizesAccessKey="True" />
                <Popup Name="Popup" Placement="Bottom" IsOpen="{TemplateBinding IsSubmenuOpen}" AllowsTransparency="True" Focusable="False" PopupAnimation="Fade">
                    <Border Name="SubmenuBorder" SnapsToDevicePixels="True" Background="Transparent">
                        <StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Cycle" />
                    </Border>
                </Popup>
            </Grid>
        </Border>
    </ControlTemplate>


    Решение вот отсюда. Там они ещё триггеры используют, но здесь не обязательно.
    Ответ написан
    1 комментарий