Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 传递要异步执行的方法_C#_.net_Winforms_Asynchronous_Async Await - Fatal编程技术网

C# 传递要异步执行的方法

C# 传递要异步执行的方法,c#,.net,winforms,asynchronous,async-await,C#,.net,Winforms,Asynchronous,Async Await,我正在创建一个Windows窗体应用程序,它对一段数据执行许多类似的操作。所有这些操作几乎相同,因此我想创建一个 使用户界面为只读 设置消息,如“正在执行操作1…” 异步执行操作,因此用户界面保持响应 将消息设置为“操作1已完成” 将接口只读设置为false 我想把这个方法称为 ExecuteOperation([method to execute], "Executing operation1") 我确信这很简单,但我在委托和任务之间迷失了方向,因此请告诉我如何编写能够运行选定方法的方法

我正在创建一个Windows窗体应用程序,它对一段数据执行许多类似的操作。所有这些操作几乎相同,因此我想创建一个

  • 使用户界面为只读
  • 设置消息,如“正在执行操作1…”
  • 异步执行操作,因此用户界面保持响应
  • 将消息设置为“操作1已完成”
  • 将接口只读设置为false
我想把这个方法称为

ExecuteOperation([method to execute], "Executing operation1")
我确信这很简单,但我在委托和任务之间迷失了方向,因此请告诉我如何编写能够运行选定方法的方法,最好是使用多个参数,以及如何调用此方法

注意:

我指的是禁用接口

MainMenu.Enabled = false;
txtData.ReadOnly = true;

您可能正在寻找类似的内容(我在这里展示了一个获取参数的方法的示例,因为您特别要求使用该示例):

如果您有各种操作可以抛出的标准异常,并且会导致某种类型的UI反馈,那么您很可能还希望在ExecuteOperation包装中添加一些异常处理


另一方面,我对名称和操作进行了重新排序,因为这使传递匿名方法作为操作变得更为简洁(IMO)。

您可能正在寻找类似的内容(我在这里展示了一个获取参数的方法的示例,因为您特别要求该示例):

如果您有各种操作可以抛出的标准异常,并且会导致某种类型的UI反馈,那么您很可能还希望在ExecuteOperation包装中添加一些异常处理


另一方面,我对名称和操作进行了重新排序,因为这使传递匿名方法作为操作更为简洁(IMO)。

类似的内容(非异步/等待-版本)如何:

void Foo(操作、字符串消息)
{
使界面只读和设置消息(消息)的方法;
BackgroundWorker工人=新的BackgroundWorker();
worker.DoWork+=(obj,arg)=>action.Invoke();
worker.RunWorkerCompleted+=
(obj,arg)=>
{
方法,该方法使接口ReadWrite();
};
worker.RunWorkerAsync();
}

在我意识到您需要异步/等待和特定任务之前,我写了这篇文章——然而,其他人已经回答了这个问题。您可以为您的操作的额外参数创建任何您想要的重载。

类似这样的内容如何(非异步/等待-版本):

void Foo(操作、字符串消息)
{
使界面只读和设置消息(消息)的方法;
BackgroundWorker工人=新的BackgroundWorker();
worker.DoWork+=(obj,arg)=>action.Invoke();
worker.RunWorkerCompleted+=
(obj,arg)=>
{
方法,该方法使接口ReadWrite();
};
worker.RunWorkerAsync();
}

在我意识到您需要异步/等待和特定任务之前,我写了这篇文章——然而,其他人已经回答了这个问题。可以为操作的额外参数创建任何重载。

可以说,可以将方法传递到方法中,但委托必须匹配。如果您有具有不同签名的方法,那么您的角度是错误的

动作和函数委托是通用的。有一个可以匹配几乎任何签名(最多16个参数),但同样,它们必须匹配方法签名。如果一个方法具有一个参数,另一个方法具有两个参数,或者两个方法具有不同类型的参数,则不能将这些参数传递给同一个委托

所以,这实际上取决于你的方法有多相似。如果它们有不同类型的参数,您可能必须“包装”这些调用

简化示例:

void Main()
{
    List<Action> actions = new List<Action>
    {
        () => Method1("myString"),
        () => Method2("myString2", "myString3")
    };
    foreach(var action in actions) InvokeAction(action);
}

void InvokeAction(Action action)
{
    action();
}

void Method1(string x)
{
    Console.WriteLine(x);
}

void Method2(string y, string z)
{
    Console.WriteLine(y);
    Console.WriteLine(z);
}
void Main()
{
列表操作=新列表
{
()=>Method1(“myString”),
()=>Method2(“myString2”、“myString3”)
};
foreach(动作中的var动作)InvokeAction(动作);
}
无效调用(操作)
{
动作();
}
无效方法1(字符串x)
{
控制台写入线(x);
}
无效方法2(字符串y、字符串z)
{
控制台写入线(y);
控制台写入线(z);
}
另一方面,如果您的方法具有相同的签名,则更简单一些:

void Main()
{
    InvokeAction(Method1, "myString");
    InvokeAction(Method2, "myString2");
}

void InvokeAction(Action<string> action, string param)
{
    action(param);
}

void Method1(string x)
{
    Console.WriteLine(x);
}

void Method2(string y)
{
    Console.WriteLine(y);
}
void Main()
{
InvokeAction(Method1,“myString”);
调用(方法2,“myString2”);
}
void InvokeAction(操作,字符串参数)
{
行动(参数);
}
无效方法1(字符串x)
{
控制台写入线(x);
}
无效方法2(字符串y)
{
控制台写入线(y);
}
现在,对于异步运行,如果您使用的是.NET4.0,那么它就像使用System.Threading.Task一样简单。您可以将我的示例方法更改为:

void InvokeAction(Action<string> action, string param)
{
    Task.Factory.StartNew(() => action(param));
}
void InvokeAction(动作动作,字符串参数)
{
Task.Factory.StartNew(()=>action(param));
}

可以说,您可以将方法传递到方法中,但代理必须匹配。如果您有具有不同签名的方法,那么您的角度是错误的

动作和函数委托是通用的。有一个可以匹配几乎任何签名(最多16个参数),但同样,它们必须匹配方法签名。如果一个方法具有一个参数,另一个方法具有两个参数,或者两个方法具有不同类型的参数,则不能将这些参数传递给同一个委托

所以,这实际上取决于你的方法有多相似。如果它们有不同类型的参数,您可能必须“包装”这些调用

简化示例:

void Main()
{
    List<Action> actions = new List<Action>
    {
        () => Method1("myString"),
        () => Method2("myString2", "myString3")
    };
    foreach(var action in actions) InvokeAction(action);
}

void InvokeAction(Action action)
{
    action();
}

void Method1(string x)
{
    Console.WriteLine(x);
}

void Method2(string y, string z)
{
    Console.WriteLine(y);
    Console.WriteLine(z);
}
void Main()
{
列表操作=新列表
{
()=>Method1(“myString”),
()=>Method2(“myString2”、“myString3”)
};
foreach(动作中的var动作)InvokeAction(动作);
}
无效调用(操作)
{
动作();
}
无效方法1(字符串x)
{
控制台写入线(x);
}
无效方法2(字符串y、字符串z)
{
控制台写入线(y);
控制台。WriteLin
void InvokeAction(Action<string> action, string param)
{
    Task.Factory.StartNew(() => action(param));
}