2015-02-03 2 views
0

Я использую таймер, чтобы обновить ListView на моем приложении, но после полсекунды, я получаю сообщение об ошибке при первом try/catch method в RefreshPlot() в PlotComponent.cs:Используя таймер для обновления интерфейса, продолжайте получать «Существует уже открытый DataReader, связанный с этим соединением, который должен быть закрыт первым».

Исключение типа 'MySql.Data.MySqlClient.MySqlException' произошел в Marketplace.exe, но не был обработан в коде пользователя

Дополнительная информация: Это уже связанное с DataReader с этим соединением, которое должно быть закрыто первым.

Что это? Я пробовал использовать using и try/catch, поэтому я не совсем понимаю, какую ошибку я могу сделать. Когда я отключу таймер, все работает хорошо. Но мне нужно получить доступ к базе данных каждые 0,5 секунды, чтобы обновить список.

Если я не делаю этого правильно, есть ли что-нибудь еще, что я могу сделать?

код выглядит следующим образом:

MainWindow.cs

public MainWindow() 
{ 
    InitializeComponent(); 

    // Reset lists 
    SetPlotList(_filterPlotReference); 

    // Refresh lists 
    Refresh(); 
} 

public void Refresh() 
{ 
    var myTimer = new System.Timers.Timer(); 
    myTimer.Elapsed += RefreshPlotList; 
    myTimer.Interval = 500; 
    myTimer.Enabled = true; 
} 

public void RefreshPlotList(object source, ElapsedEventArgs e) 
{ 
    PlotComponent.RefreshPlot(); 
    Dispatcher.Invoke(() => 
    { 
     if (!string.IsNullOrWhiteSpace(FilterTextBox.Text) && 
      (!Regex.IsMatch(FilterTextBox.Text, "[^0-9]"))) 
     { 
      _filterPlotReference = Convert.ToInt32(FilterTextBox.Text); 
     } 
    }); 
    SetPlotList(_filterPlotReference); 
    FocusPlotItem(_focusPlotReference); 
} 

public void SetPlotList(int filterReference) 
{ 
    // Fill plot list view 
    List<PlotComponent.PlotList> plotList = PlotComponent.SelectPlotLists(filterReference); 

    // Find the plot list item in the new list 
    PlotComponent.PlotList selectPlotList = 
     plotList.Find(x => Convert.ToInt32(x.PlotId) == _focusPlotReference); 

    Dispatcher.Invoke(
     (() => 
     { 
      PlotListView.ItemsSource = plotList; 
      if (selectPlotList != null) 
      { 
       PlotListView.SelectedItem = selectPlotList; 
      } 
     })); 

    int jobSum = 0; 
    int bidSum = 0; 
    foreach (PlotComponent.PlotList item in PlotListView.Items) 
    { 
     jobSum += Convert.ToInt32(item.Jobs); 
     bidSum += Convert.ToInt32(item.Bids); 
    } 

    // Determine job/bid list ratio 
    Dispatcher.BeginInvoke(
     new ThreadStart(() => JobBidRatioTextBlock.Text = jobSum + " jobs - " + bidSum + " bids")); 
} 

private void FocusPlotItem(int focusPlotReference) 
{ 
    Dispatcher.Invoke(
     (() => 
     { 
      PlotComponent.PlotList plotList = 
       PlotListView.Items.OfType<PlotComponent.PlotList>() 
        .FirstOrDefault(p => Convert.ToInt32(p.PlotId) == focusPlotReference); 
      if (plotList == null) return; 
      //get visual container 
      var container = PlotListView.ItemContainerGenerator.ContainerFromItem(plotList) as ListViewItem; 
      if (container == null) return; 
      container.IsSelected = true; 
      container.Focus(); 
     })); 
} 

DbConnect.cs

http://pastebin.com/pZ0PGrg1

PlotComponent.cs

http://pastebin.com/xiRhKyMM

спасибо за вашу помощь заранее.

ответ

1

Вот пример, чтобы заблокировать таймер, пока он закончит свою работу:

bool timerRunning = false; // define it as a global variable 

// then in your timer process add this easy check 
public void RefreshPlotList(object source, ElapsedEventArgs e) 
{ 
    if(timerRunning) return; // return if it is busy 
    timerRunning = true; // set it to busy 

    PlotComponent.RefreshPlot(); 
    Dispatcher.Invoke(() => 
    { 
     if (!string.IsNullOrWhiteSpace(FilterTextBox.Text) && 
      (!Regex.IsMatch(FilterTextBox.Text, "[^0-9]"))) 
     { 
      _filterPlotReference = Convert.ToInt32(FilterTextBox.Text); 
     } 
    }); 
    SetPlotList(_filterPlotReference); 
    FocusPlotItem(_focusPlotReference); 

    timerRunning = false; // reset it for next time use 
} 

PS: Я редактировал другой ответ, добавив (точно) этот ответ, то я получил отклонен, коллегиальный обзор говорит

Это изменение предназначалось для ответа на автора сообщения и не делает смысл как редактирование. Это должно было быть написано как комментарий или ответ

Я не сомневаюсь, что они читать редактировать и оценить его, не говоря уже о том, что он не вписывается в комментарии, так что здесь я опубликуйте его как ответ

0

Можно ли отключить таймер до завершения функции RefreshPlotList?

Может быть в начале функции отключить таймер и в конце функции RefreshPlotList Включить таймер. Я предполагаю, что функция RefreshPlotList занимает больше 0,5 секунды, а другой вызов выполняется до того, как текущий закончен.

+0

Можете ли вы показать мне пример того, как я отключу его? – methuselah

Смежные вопросы

 Смежные вопросы