列表问题.明确的,对象同步方法从未同步的代码块中调用

本文关键字:代码 同步 调用 同步方法 问题 对象 列表 | 更新日期: 2023-09-27 18:17:54

我很难找出List.Clear()方法的问题。我的应用程序在不同的时间崩溃,例如30分钟到5小时。这是随机发生的。

下面的代码是在后台线程中启动的。我也有一些其他的线程同时工作,有些可以使用loggedData1 &loggedData2变量。
try
{
    while (true)
    {
        if (LoggingEnabled)
        {
            var stopwatch = Stopwatch.StartNew();
            #region - Reset logging variables
            loggedData2.Clear(); // List
            loggedData1.Clear(); // List
            #endregion
            // Lots of more code
        }
    }
}
catch (Exception ex)
{
    // Crashing exception given is "Object synchronization method was called from an unsyncronized block of code"
}

我怎么能解决这个问题,我对线程很陌生。谢谢你的帮助。

列表问题.明确的,对象同步方法从未同步的代码块中调用

这个列表似乎被绑定到一个视图。所以在这种情况下,从另一个线程中清除列表是一个非法的跨线程调用。您必须设置正确的同步上下文或实现列表的异步版本。下面是一个ObservableCollection

的例子
public class AsyncObservableCollection<T> : ObservableCollection<T>
{
  private readonly SynchronizationContext _synchronizationContext = SynchronizationContext.Current;
  public AsyncObservableCollection()
  {
  }
  public AsyncObservableCollection(IEnumerable<T> list) : base(list)
  {
  }
  protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs e)
  {
    if (SynchronizationContext.Current == _synchronizationContext)
    {
      // Execute the CollectionChanged event on the current thread
      RaiseCollectionChanged(e);
    }
    else
    {
      // Post the CollectionChanged event on the creator thread
      _synchronizationContext.Post(RaiseCollectionChanged, e);
    }
  }
  private void RaiseCollectionChanged(object param)
  {
    // We are in the creator thread, call the base implementation directly
    base.OnCollectionChanged((NotifyCollectionChangedEventArgs) param);
  }
  protected override void OnPropertyChanged(PropertyChangedEventArgs e)
  {
    if (SynchronizationContext.Current == _synchronizationContext)
    {
      // Execute the PropertyChanged event on the current thread
      RaisePropertyChanged(e);
    }
    else
    {
      // Post the PropertyChanged event on the creator thread
      _synchronizationContext.Post(RaisePropertyChanged, e);
    }
  }
  private void RaisePropertyChanged(object param)
  {
    // We are in the creator thread, call the base implementation directly
    base.OnPropertyChanged((PropertyChangedEventArgs) param);
  }
}