无法获得MethodInvoker来返回bool

时间:2012-05-09 15:03:40

标签: c# multithreading

我需要从我的线程中访问共享日志文件,所以我现在尝试使用MethodInvoker读取文件并返回bool,具体取决于它是否找到了一个条目..但是得到这个错误,无法弄清楚怎么让它给我一个布尔:

  

无法将匿名方法转换为委托类型   '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;
                       }
                       ));
    }

3 个答案:

答案 0 :(得分: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;
        }
    ));

更多信息

答案 1 :(得分:4)

MethodInvoker无法返回任何内容。该委托具有void返回类型。如果您需要返回一个值,则需要使用其他代理(例如Func<bool>)。

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

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

答案 2 :(得分:0)

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