2015-10-29 2 views
0

Есть класс:LINQ и динамический список Тип

public class SignalRounding 
{ 
    public DateTime LastUpdated { get; set; } 
    public int Quantity { get; set; } 
    public string symbol { get; set; } 
    public double price { get; set; } 
    public double round { get; set; } 
} 
public class SignalRoundingView 
{ 
    public DateTime LastUpdated { get; set; } 
    public int Quantity { get; set; } 
    public string symbol { get; set; } 
    public double price { get; set; } 
    public double round { get; set; } 
} 

Создать список

public static List<SignalRounding> SignalR; 
SignalR = new List<SignalRounding>(); 
ListView.ItemsSource = SignalR; 
ListView.Items.Refresh(); 

Добавить информацию с определенными параметрами

try 
{ 
var r = SignalR.Where(t => t.LastUpdated >= DateTime.Now.AddMinutes(-10)) 
.GroupBy(g => g.symbol) 
.Select(s => new SignalRoundingView() 
    { 
    LastUpdated = s.Max(x => x.LastUpdated), 
    Quantity = s.Count(), 
    symbol = s.Key, 
    price = s.Single(l => l.LastUpdated == s.Max(x => x.LastUpdated)).price, 
    round = s.Single(l => l.LastUpdated == s.Max(x => x.LastUpdated)).round 
    }) 
.OrderByDescending(x => x.LastUpdated) 
.ThenByDescending(x => x.Quantity).ToList(); 

Filter3List.ItemsSource = r; 
Filter3List.Items.Refresh(); 
} 
catch (Exception){throw;} 

List<SignalRounding> SignalR динамична - иногда возникает ошибка , Со следующим описанием: Коллекция была изменена; операция не может быть выполнена перечислением.

Как это исправить?

+3

Вместо этого используйте безопасный список потоков? например 'ConcurrentBag ' – DavidG

+0

Я использую это: 'if (Filter3List.Dispatcher.Thread == Thread.CurrentThread) {code} else Filter3List.Dispatcher.BeginInvoke (новый ThreadStart (delegate {}));' – alexander

+0

Но у вас все еще есть несколько потоков доступ к списку, который будет генерировать исключения. Изменить 'List ' to ConcurrentBag ' – DavidG

ответ

1

Убедитесь, что вы не разрешаете нить проходить через список (запрос Linq), в то время как к нему добавляется другой поток. Для этого вы можете использовать блокировку. Существует ограничение производительности, поэтому вам нужно решить, будет ли это решение работать достаточно хорошо для вас, в зависимости от того, насколько быстро вы добавляете новые объекты в список и как длинный список.

private object myLock = new Object(); 

void AddToList(SignalR s) 
{ 
    lock(myLock) { 
     SignalR.Add(s); 
    } 
} 

void UpdateList() { 
    lock(myLock) 
    { 
     var r = SignalR.Where(...).ToList(); 

     Filter3List.ItemsSource = r; 
     Filter3List.Items.Refresh(); 
    } 
} 
1

У вас есть несколько потоков, обращающихся к вашему списку, которые будут генерировать исключения. Вместо List<T> используйте ConcurrentBag<T>:

public static ConcurrentBag<SignalRounding> SignalR; 

Примечание: Это в System.Collections.Concurrent пространстве имен.

+0

Он разрушает все методы, связанные с типом списка – alexander

+0

Я не понимаю, что вы имеете в виду. – DavidG

+0

Все еще есть ошибки во время замены Список to ConcurrentBag alexander

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