BeginInvoke не передает данные, но использование Invoke вызывает исключение - PullRequest
0 голосов
/ 25 марта 2011

У меня есть приложение Windows Forms, которое показывает данные в виде сетки. Данные автоматически обновляются (выбираются из БД) из фонового рабочего потока. Таким образом, чтобы избежать каких-либо перекрестных ссылок, в методе DoWork фонового потока я вызываю GridView.BeginInvoke () и передаю список сообщений. Но в методах делегатов список сообщений пуст.

Если я использую GridView.invoke (), messageList действительно содержит значения, но иногда возникает исключение, которое говорит, что «объект используется в другом месте», которое, я считаю, вызвано из-за ссылки на элемент управления UI на Пользовательский интерфейс.

Как я могу решить эту проблему?

    public delegate void AddMessagesDelegate(List<ClientMessage> tempMessageList);

    private void SearchWorkerDoWork(object sender, DoWorkEventArgs e)
    {
        List<ClientMessage> partList = new List<ClientMessage>();

        View.GridViewtMain.Invoke(new InvokeDelegate(ClearMessagesFromGrid));
        //View.GridViewtMain.BeginInvoke(new InvokeDelegate(ClearMessagesFromGrid));
        partList.AddRange(Model.LoadSearchResult());
        View.GridViewtMain.Invoke(new AddMessagesDelegate(AddMessagesToGrid), new object[] {partList});
        //View.GridViewtMain.BeginInvoke(new AddMessagesDelegate(AddMessagesToGrid), new object[] {partList});
        while (!isCancelled && (partList.Count > 0))
        {
            partList.Clear();
            partList.AddRange(Model.LoadSearchResult());
            View.GridViewtMain.Invoke(new AddMessagesDelegate(AddMessagesToGrid), new object[] {partList});
            //View.GridViewtMain.BeginInvoke(new AddMessagesDelegate(AddMessagesToGrid), new object[] {partList});
        }
    }

    private void ClearMessagesFromGrid()
    {
        messageDataSource.Clear();
    }

    private void AddMessagesToGrid(List<ClientMessage> tempMessageList)
    {
        View.GridViewMain.BeginDataUpdate();

        foreach (ClientMessage message in tempMessageList)
        {
            messageDataSource.Add(message);
        }
        View.GridViewMain.GridControl.DataSource = messageDataSource;           
        View.GridViewMain.EndDataUpdate();
    }

1 Ответ

2 голосов
/ 25 марта 2011
  partList.Clear();

Вы разместили код, который работает вместо кода, с которым у вас проблема.Я приму BeginInvoke вместо Invoke.Метод partList.Clear () собирается очистить список, за до цель делегата может использовать список.Вы должны создать новый экземпляр списка после вызова BeginInvoke.Теперь поток пользовательского интерфейса может без проблем работать со старым списком.Примерно

    while (!isCancelled)
    {
        partList = new List<ClientMessage>();
        partList.AddRange(Model.LoadSearchResult());
        if (partList.Count == 0) break;
        View.GridViewtMain.BeginInvoke(new AddMessagesDelegate(AddMessagesToGrid), new object[] {partList});
    }
...