Answer the question
In order to leave comments, you need to log in
Why does an "Unhandled exception of type 'System.ArgumentOutOfRangeException' in mscorlib.dll" occur?
Good afternoon
I have a WPF application. The window has a DataGrid and a TextBox.
There is a separate Connector class, it receives data, and as data is received, the contents of the DataGrid are updated. Data is received in a separate thread, which I launch like this: new Thread(() => {...})..Start();
From this thread, when new data is received, I update the contents of the DataGrid:
Application.Current.Dispatcher.Invoke((ThreadStart)delegate { win.SetQuote(quote_list); });
Application.Current.Dispatcher.Invoke((ThreadStart)delegate { win.SetLog(QuoteStr); });
using System;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Data;
using System.IO;
using System.IO.MemoryMappedFiles;
namespace UTox
{
public class QuoteItem
{
public String Price { get; set; }
public String Volume { get; set; }
}
class Connector
{
public volatile bool Run = true;
private MainWindow win = (MainWindow)Application.Current.MainWindow;
private List<QuoteItem> quote_list;
...
public Connector()
{
...
quote_list = new List<QuoteItem>();
...
}
...
//Получает данные
private void GettingQuoteData()
{
new Thread(() =>
{
string QuoteStr = "";
string[] QuoteStrBid, QuoteStrParts;
//Постоянный цикл в отдельном потоке
while (Run)
{
QuoteStr = GetTerminalQuoteData(); //Получает строчку из памяти
//Если данные есть
if (QuoteStr != "00" && QuoteStr != "" && QuoteStr != "0" && QuoteStr != "-1")
{
//Если строчку ниже раскоментировать, то ошибка не возникает. Метод win.SetLog(QuoteStr) выводит строку QuoteStr в TexBox окна приложения
//Application.Current.Dispatcher.Invoke((ThreadStart)delegate { win.SetLog(QuoteStr); });
ClearTerminalQuoteData();//подтверждает что данные получены
//Разделяет снимок СТАКАНА на составляющие
QuoteStrParts = QuoteStr.Split('@');
QuoteStrBid = QuoteStrParts[0].Split(';');
quote_list.Clear();
if (QuoteStrBid.Length > 9 )
{
int i = 9;
while (i > 0)
{
quote_list.Add(new QuoteItem() { Volume = QuoteStrBid[i - 1], Price = QuoteStrBid[i] });
i = i - 2;
}
}
//Обновим содержимое DataGrid
Application.Current.Dispatcher.Invoke((ThreadStart)delegate { win.SetQuote(quote_list); });
QuoteStrParts = QuoteStrBid = null;
}
Thread.Sleep(100);
}
}).Start();
}
...
}
}
Answer the question
In order to leave comments, you need to log in
You are using in two different threads a List which is not thread safe. Most likely this is the problem. Either use thread-safe lists, such as ConcurrentQuery, or copy the entire list before passing it to win, such as using ToList() or ToArray().
Learn more about thread-safe collections
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question