2

我需要从我的线程中访问共享日志文件,所以我现在尝试使用 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;
                       }
                       ));
    }
4

3 回答 3

4

描述

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;
        }
    ));

更多信息

于 2012-05-09T15:05:47.540 回答
4

MethodInvoker不能返回任何东西。委托有一个void返回类型。如果需要返回值,则需要使用不同的委托(例如Func<bool>)。

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

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

于 2012-05-09T15:05:54.680 回答
0

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

我会使用Task该类在后台读取文件。用于StartNewFunc<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);
}
于 2012-05-09T15:17:19.580 回答