【问题标题】:'Await' not returning to the UI thread when logging with log4net使用 log4net 记录时“等待”不返回 UI 线程
【发布时间】:2018-05-14 03:36:00
【问题描述】:

我有一个 WPF-MVVM 应用程序。我想在加载和处理文件时使用asyncawait 使我的UI 响应。当 awaited 的方法使用 log4net 进行日志记录时,我收到异常“调用线程无法访问此对象,因为不同的线程拥有它”。

// The method returns 'void' because it is used by a DelegateCommand!
private async void LoadAndProcessFileAsync()
{
   this.MyBindingList.Clear(); // Works fine
   var importer = await Task.Run(() => new Importer());
   this.MyBindingList.Clear(); // Exception
}

进口商所做的只是:

public class Importer
{
  private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);

  public Importer()
  {
    log.Info("Test");
  }
}

如果我注释掉log.Info... 和静态ILog-变量,一切正常。如果我执行以下操作也会出现问题:

private async void LoadAndProcessFileAsync()
{
   this.MyBindingList.Clear(); // Works fine
   var test = await Task.Run(() => Math.Sqrt(9));
   var importer = new Importer();
   this.MyBindingList.Clear(); // Exception
}

如果我在 async 方法中根本不使用 await,它就会消失。

为什么会这样?如何同时使用await 和登录? (我正在使用使用 log4net 的第三方库,所以我无法更改该代码...)。

【问题讨论】:

  • 如果您将日志设为非静态,则可以肯定不会出现问题。静态日志意味着您在多个线程中使用相同的对象;因此,为什么除了主线程(在初始化期间创建所有静态对象的线程)之外的线程在访问它时存在问题。
  • 如果Importer 是您不拥有的第三方库,您怎么知道它会做什么?
  • @Evk:我写了Importer 来重现错误。第三方库是 xBim(开源),我必须检查他们如何准确地处理他们的日志记录。
  • 所以澄清一下,这是重现问题的确切代码,而不是一些伪代码?
  • 那么值得发布可以重现此行为的确切代码,而无需剥离任何内容(嗯,与重现相关的任何内容),因为使用当前代码它是不可重现的。

标签: c# wpf async-await log4net ui-thread


【解决方案1】:

您的异步方法示例都返回 void,因此不会等待,为了等待任务,它必须至少返回 Task,并且如果您有“调用线程无法访问此对象,因为不同的线程拥有它”问题尝试使用调度程序:

Application.Current.Dispatcher.Invoke(() => {Your Action;} );

异步方法本质上在新线程上运行

【讨论】:

  • 不等待async void-方法是不正确的,这很好用。我试过你的建议,但是,Application.Currentnull!这可能与我的设置有关,我正在通过 C++/CLI-Wrapper 从 Fortran 调用 C#...如果错误发生在简单的 C# 应用程序中,我将不得不尝试。
  • async methods by their very nature run on a new thread 也不是真的。如果合适,任务调度程序可以在调用线程上同步运行async 方法。此外,还有一些 IO 密集型任务根本不需要任何线程。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-04
  • 1970-01-01
相关资源
最近更新 更多