【问题标题】:How to get the result of a Task inside a Dispatcher Timer tick?如何在 Dispatcher Timer 刻度内获取任务的结果?
【发布时间】:2018-02-20 12:36:05
【问题描述】:

我有一个按以下方式定义的调度程序计时器:

DispatcherTimer dispatcherTime;

public AppStartup()
{
   dispatcherTimer = new DispatcherTimer();
   dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
   dispatcherTimer.Interval = new TimeSpan(0, 0, 5);
   dispatcherTimer.Start();
}

Tick 事件中我需要触发一个异步方法:

 private void dispatcherTimer_Tick(object sender, EventArgs e)
 {
     bool result = CheckServer().Result;

     if(result)
     {
        //start the app
     }
     else 
     {
        //display message server not available
     }
}

问题是我得到了这个异常:

在 System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions) 在 System.Threading.Tasks.Task1.GetResultCore(Boolean waitCompletionNotification) in System.Threading.Tasks.Task1.get_Result() 在 App.dispatcherTimer_Tick(Object sender, EventArgs e) 在 System.Windows.Threading.DispatcherTimer.FireTick(未使用的对象) 在 System.Windows.Threading.ExceptionWrapper.InternalRealCall(委托回调,对象 args,Int32 numArgs) in System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)

方法CheckServer有这个代码:

public async Task<bool> CheckServer()
{
   bool result = false;

   try
   {
      await AnotherMethod();
   }
   catch(Exception ex)
   {
      await this.ShowMessageAsync("attention", "an exception occurred: " + ex.message);
     return false;
   }

   return result;
}

我该如何处理这种情况?

【问题讨论】:

  • await this.ShowMessageAsync 这是什么?无论如何您都不需要它,尤其是使用 WPF 和数据绑定。充其量它会阻塞 UI 线程,或者抛出一个跨线程访问异常。最坏的情况会导致死锁。使用IProgress&lt; T&gt; 报告事件,不要尝试从后台线程访问 UI 线程
  • @PanagiotisKanavos ShowMessageAsync 由 MahApp 框架提供,必须使用 await 声明

标签: c# wpf multithreading


【解决方案1】:

声明事件处理程序asyncawait CheckServer 任务:

private async void dispatcherTimer_Tick(object sender, EventArgs e)
{
    bool result = await CheckServer();

    ...
}

编辑:可能会丢弃 CheckServer 方法并像这样编写 Tick 处理程序:

private async void dispatcherTimer_Tick(object sender, EventArgs e)
{
    try
    {
        await AnotherMethod();
    }
    catch (Exception ex)
    {
        await ShowMessageAsync("attention", "an exception occurred: " + ex.message);
    }
 }

【讨论】:

  • 异常消失了,但现在当到达这一行时我得到空引用异常:await this.ShowMessageAsync("attention", "an exception occurred: " + ex.message); 为什么?
  • @IlRagazzoDiCampagna 因为您正试图访问 ShowMessageAsync 中的 UI 线程。别。使用IProgress&lt; T&gt;接口报告进度或错误
  • @IlRagazzoDiCampagna 也发布ShowMessageAsync的代码
  • @IlRagazzoDiCampagna 顺便说一句,您可能不应该甚至尝试处理 CheckServer 中的异常,让 Tick 处理程序来执行此操作并显示一个顶级警告窗口阻止消息框
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-10
  • 1970-01-01
  • 2017-02-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多