将 void 转换为字符串 - void 到对象问题?
converting void to string - void to object issue?
我有以下多线程代码,它获取服务器列表并异步运行繁重的操作,繁重的操作 returns 结果,我试图用结果填充多行文本框(要么作为完成时的批处理或作为每个任务 returns ),我已经添加了一些代码以希望执行此任务,但是下面的三行带有正确的评论导致我们混淆了 void 到 static 和 void 到对象 :( 任何关于我需要更改的内容收到了很多提示....谢谢
这是代码:-
public partial class Form1 : Form
{
Progress<string> progressReporter = new Progress<string>();
CancellationTokenSource cancelSource;
public Form1()
{
InitializeComponent();
progressReporter.ProgressChanged += progressManager_ProgressChanged;
}
async private void btnStart_Click(object sender, EventArgs e)
{
btnStart.Enabled = false;
btnCancel.Enabled = true;
cancelSource = new CancellationTokenSource();
textBox1.Text = await Task.Run(() => PerfromTaskAction(cancelSource.Token), cancelSource.Token); //--Cannot implicity convert type 'void' to 'string'
await Task.Run(() => PerfromTaskAction(cancelSource.Token), cancelSource.Token);
lblStatus.Text = "Completed.";
btnStart.Enabled = true;
btnCancel.Enabled = false;
}
static async Task PerfromTaskAction(CancellationToken ct)
{
StringBuilder sb = new StringBuilder();
object[] arrObjects = new object[] { "SERVER1", "SERVER2", "SERVER3", "SERVER4" };
IList<Task> tasks = new List<Task>();
foreach (object i in arrObjects)
{
if (ct.IsCancellationRequested) break;
sb.Append(string.Format("{0}", tasks.Add(Task.Run(() => HeavyOperation(i.ToString()))))); //-- Argument 2: cannot convert from 'void' to 'object'
tasks.Add(Task.Run(() => HeavyOperation(i.ToString())));
}
await Task.WhenAll(tasks).ConfigureAwait(false);
return sb.ToString(); //--Since 'Form1.PerfromTaskAction(CancellationToken)' is an async method that returns 'Task', a return keyword must not be followed by an object expression?
}
void progressManager_ProgressChanged(object sender, string e)
{
lblStatus.Invoke((Action)(() => lblStatus.Text = e));
}
static string HeavyOperation(string i)
{
PowerShell ps = PowerShell.Create();
ps.AddCommand("invoke-command");
ps.AddParameter("computername", i);
ps.AddParameter("scriptblock", ScriptBlock.Create("get-vmreplication | select State"));
Collection<PSObject> result = ps.Invoke();
return(result[0].Properties["State"].Value.ToString());
}
private void btnCancel_Click(object sender, EventArgs e)
{
cancelSource.Cancel();
}
}
将方法签名更改为
static async Task<string> PerfromTaskAction(CancellationToken ct)
return Task(sb.ToString());
然后
textBox1.Text = await Task.Run(() => PerfromTaskAction(cancelSource.Token), cancelSource.Token).Result;
你有 3 个错误,所以一次解决一个问题:
//-- Argument 2: cannot convert from 'void' to 'object'
sb.Append(string.Format("{0}", tasks.Add(Task.Run(() => HeavyOperation(i.ToString())))));
List<T>.Add
的 return 类型是 void
。所以它不能用作string.Format
的第二个参数。您想要对这行代码做什么,这里一点都不清楚,所以我无法提出修复建议。
//--Since 'Form1.PerfromTaskAction(CancellationToken)' is an async method that returns 'Task', a return keyword must not be followed by an object expression
return sb.ToString();
这个错误是说你在一个 async Task
方法中(这是 void
的异步等价物),所以它不能有一个 return 值。然而您的代码正在尝试 return 一个值。
这里的修复是将方法签名更改为 return Task<string>
:
static async Task<string> PerfromTaskAction(CancellationToken ct)
至于最后的错误:
//--Cannot implicity convert type 'void' to 'string'
textBox1.Text = await Task.Run(() => PerfromTaskAction(cancelSource.Token), cancelSource.Token);
如果PerformTaskAction
return是Task
,那么Task.Run(() => PerfromTaskAction(cancelSource.Token), cancelSource.Token)
的return类型也是Task
,这表示类型await Task.Run(() => PerfromTaskAction(cancelSource.Token), cancelSource.Token)
的 void
。而且您不能将 void
分配给 textBox1.Text
.
最后一个错误的修复(更改为 Task<string>
)也修复了这个错误。 Task.Run(() => PerfromTaskAction(cancelSource.Token), cancelSource.Token)
的 return 类型现在是 Task<string>
,await Task.Run(() => PerfromTaskAction(cancelSource.Token), cancelSource.Token)
的类型现在是 string
.
根据评论更新:
因为你想 return 所有的字符串,当它们全部完成时,这样做更容易 without StringBuilder
:
static async Task<string> PerfromTaskAction()
{
object[] arrObjects = new object[] { "SERVER1", "SERVER2", "SERVER3", "SERVER4" };
var tasks = arrObjects.Select(i => Task.Run(() => HeavyOperation(i.ToString())));
var results = await Task.WhenAll(tasks).ConfigureAwait(false);
return string.Join("", results);
}
请注意,由于 CancellationToken
未在 HeavyOperation
中使用,因此可以将其从 PerformTaskAction
签名中删除。
我有以下多线程代码,它获取服务器列表并异步运行繁重的操作,繁重的操作 returns 结果,我试图用结果填充多行文本框(要么作为完成时的批处理或作为每个任务 returns ),我已经添加了一些代码以希望执行此任务,但是下面的三行带有正确的评论导致我们混淆了 void 到 static 和 void 到对象 :( 任何关于我需要更改的内容收到了很多提示....谢谢
这是代码:-
public partial class Form1 : Form
{
Progress<string> progressReporter = new Progress<string>();
CancellationTokenSource cancelSource;
public Form1()
{
InitializeComponent();
progressReporter.ProgressChanged += progressManager_ProgressChanged;
}
async private void btnStart_Click(object sender, EventArgs e)
{
btnStart.Enabled = false;
btnCancel.Enabled = true;
cancelSource = new CancellationTokenSource();
textBox1.Text = await Task.Run(() => PerfromTaskAction(cancelSource.Token), cancelSource.Token); //--Cannot implicity convert type 'void' to 'string'
await Task.Run(() => PerfromTaskAction(cancelSource.Token), cancelSource.Token);
lblStatus.Text = "Completed.";
btnStart.Enabled = true;
btnCancel.Enabled = false;
}
static async Task PerfromTaskAction(CancellationToken ct)
{
StringBuilder sb = new StringBuilder();
object[] arrObjects = new object[] { "SERVER1", "SERVER2", "SERVER3", "SERVER4" };
IList<Task> tasks = new List<Task>();
foreach (object i in arrObjects)
{
if (ct.IsCancellationRequested) break;
sb.Append(string.Format("{0}", tasks.Add(Task.Run(() => HeavyOperation(i.ToString()))))); //-- Argument 2: cannot convert from 'void' to 'object'
tasks.Add(Task.Run(() => HeavyOperation(i.ToString())));
}
await Task.WhenAll(tasks).ConfigureAwait(false);
return sb.ToString(); //--Since 'Form1.PerfromTaskAction(CancellationToken)' is an async method that returns 'Task', a return keyword must not be followed by an object expression?
}
void progressManager_ProgressChanged(object sender, string e)
{
lblStatus.Invoke((Action)(() => lblStatus.Text = e));
}
static string HeavyOperation(string i)
{
PowerShell ps = PowerShell.Create();
ps.AddCommand("invoke-command");
ps.AddParameter("computername", i);
ps.AddParameter("scriptblock", ScriptBlock.Create("get-vmreplication | select State"));
Collection<PSObject> result = ps.Invoke();
return(result[0].Properties["State"].Value.ToString());
}
private void btnCancel_Click(object sender, EventArgs e)
{
cancelSource.Cancel();
}
}
将方法签名更改为
static async Task<string> PerfromTaskAction(CancellationToken ct)
return Task(sb.ToString());
然后
textBox1.Text = await Task.Run(() => PerfromTaskAction(cancelSource.Token), cancelSource.Token).Result;
你有 3 个错误,所以一次解决一个问题:
//-- Argument 2: cannot convert from 'void' to 'object'
sb.Append(string.Format("{0}", tasks.Add(Task.Run(() => HeavyOperation(i.ToString())))));
List<T>.Add
的 return 类型是 void
。所以它不能用作string.Format
的第二个参数。您想要对这行代码做什么,这里一点都不清楚,所以我无法提出修复建议。
//--Since 'Form1.PerfromTaskAction(CancellationToken)' is an async method that returns 'Task', a return keyword must not be followed by an object expression
return sb.ToString();
这个错误是说你在一个 async Task
方法中(这是 void
的异步等价物),所以它不能有一个 return 值。然而您的代码正在尝试 return 一个值。
这里的修复是将方法签名更改为 return Task<string>
:
static async Task<string> PerfromTaskAction(CancellationToken ct)
至于最后的错误:
//--Cannot implicity convert type 'void' to 'string'
textBox1.Text = await Task.Run(() => PerfromTaskAction(cancelSource.Token), cancelSource.Token);
如果PerformTaskAction
return是Task
,那么Task.Run(() => PerfromTaskAction(cancelSource.Token), cancelSource.Token)
的return类型也是Task
,这表示类型await Task.Run(() => PerfromTaskAction(cancelSource.Token), cancelSource.Token)
的 void
。而且您不能将 void
分配给 textBox1.Text
.
最后一个错误的修复(更改为 Task<string>
)也修复了这个错误。 Task.Run(() => PerfromTaskAction(cancelSource.Token), cancelSource.Token)
的 return 类型现在是 Task<string>
,await Task.Run(() => PerfromTaskAction(cancelSource.Token), cancelSource.Token)
的类型现在是 string
.
根据评论更新:
因为你想 return 所有的字符串,当它们全部完成时,这样做更容易 without StringBuilder
:
static async Task<string> PerfromTaskAction()
{
object[] arrObjects = new object[] { "SERVER1", "SERVER2", "SERVER3", "SERVER4" };
var tasks = arrObjects.Select(i => Task.Run(() => HeavyOperation(i.ToString())));
var results = await Task.WhenAll(tasks).ConfigureAwait(false);
return string.Join("", results);
}
请注意,由于 CancellationToken
未在 HeavyOperation
中使用,因此可以将其从 PerformTaskAction
签名中删除。