无法让 MethodInvoker 返回布尔值

本文关键字:返回 布尔值 MethodInvoker | 更新日期: 2023-09-27 18:33:50

我需要从我的线程中访问共享日志文件,所以我现在尝试使用 MethodInvoker 读取文件并根据它是否找到条目返回一个布尔值。但是收到此错误,无法弄清楚如何让它返回我一个布尔值:

无法将匿名方法转换为委托类型 "System.Windows.Forms.MethodInvoker",因为某些返回类型 在块中不能隐式转换为委托返回 类型

    private void searchLogInThread(string msg, string fileName)
    {
        Invoke(new MethodInvoker(
                       delegate
                       {
                           StreamReader re = File.OpenText(fileName);
                           string input = null;
                           while ((input = re.ReadLine()) != null)
                           {
                               if (input.Contains(msg))
                               {
                                   re.Close();
                                   return true;
                               }
                           }
                           re.Close();
                           return false;
                       }
                       ));
    }

无法让 MethodInvoker 返回布尔值

描述

方法调用程序是一个没有结果的委托。您需要创建自己的。

样本

public delegate bool MethodInvokerWithBooleanResult();
Invoke(new MethodInvokerWithBooleanResult(
             delegate
             {
                            // do something and return a bool
                            return true;
             }
         ));

更新

另一种方法是使用Func<bool>

Invoke(new Func<bool>(
        delegate
        {
                    // do something and return a bool
                    return true;
        }
    ));

更多信息

  • MSDN - 委托 (C# 编程指南)

MethodInvoker无法返回任何内容。委托具有void返回类型。如果需要返回值,则需要使用不同的委托(例如 Func<bool> )。

假设这是在一个控件内,我认为无论如何你都以错误的方式进行这一切 - 你使用的是Control.Invoke,它将在 UI 线程中执行所有这些代码(读取文件)。别这样。

此外,没有任何迹象表明您将如何使用结果......基本上,我认为您需要重新考虑您的设计。此刻很困惑。

MethodInvoker

定义返回类型。有各种不同的方法可以从匿名方法或 lambda 表达式中获取返回值。但是,您似乎可能对如何使用Invoke存在根本性的误解。您提供的代码根本不会在后台线程上运行。

我会使用 Task 类在后台读取文件。使用 StartNew 使Func<TResult>委托在后台线程上运行。然后,可以调用 ContinueWith 将控制权转移回 UI,您可以在其中提取返回值并使用它操作任何控件。

private void searchLogInThread(string msg, string fileName)
{
  Task.Factory
    .StartNew(() =>
    {
      // This executes on a background thread.
      using (StreamReader re = File.OpenText(fileName))
      {
        string input = null;
        while ((input = re.ReadLine()) != null)
        {
          if (input.Contains(msg))
          {
            return true;
          }
        }
        return false;
      }
    })
    .ContinueWith(task =>
    {
      // This executes on the UI thread.
      bool result = task.Result; // Extract result from the task here.
      MessageBox.Show(result.ToString());
    }, TaskScheduler.FromCurrentSynchronizationContext);
}