2017-05-12 31 views
-2

我有以下多线程代码,它采取服务器列表和异步运行繁重的操作,繁重的操作返回结果,并试图填充多行文本框的结果(作为批处理完成或作为每个任务返回),我已经添加了一些代码,希望执行这项任务,但下面三行与正确的意见导致我们混淆关于无效静态和无效的对象:(任何提示大大收到我需要改变.. ..谢谢将void转换为字符串 - 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(); 
    } 

} 
+1

1.你的问题是什么? 2. *“'void' to object”*没有任何意义 - 'void'意味着一个方法不会返回任何东西,您不能将“nothing”转换为一个对象(并且它看起来并没有在代码中发生?)3.所有这些代码应该显示什么?它绝对不是[mcve] – UnholySheep

+0

如果你想要返回字符串,将方法改为静态异步任务' –

+2

“将void转换为字符串”...我会阻止你。 – Abion47

回答

2

你有三个错误,所以把他们一次一个:

//-- Argument 2: cannot convert from 'void' to 'object' 
sb.Append(string.Format("{0}", tasks.Add(Task.Run(() => HeavyOperation(i.ToString()))))); 

List<T>.Add返回类型是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的)的时候,所以它不能有返回值。然而你的代码试图返回一个值。

这里的修复方法就是改变方法签名返回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返回Task,那么Task.Run(() => PerfromTaskAction(cancelSource.Token), cancelSource.Token)返回类型为也Task,这意味着await Task.Run(() => PerfromTaskAction(cancelSource.Token), cancelSource.Token)的类型是void。并且您不能采取void并将其分配给textBox1.Text

修复了最后一个错误(更改为Task<string>)也修复了这一错误。返回类型Task.Run(() => PerfromTaskAction(cancelSource.Token), cancelSource.Token)现在是Task<string>await Task.Run(() => PerfromTaskAction(cancelSource.Token), cancelSource.Token)的类型现在是string

从评论更新:

既然你想返回所有的字符串时,他们都齐全,这是比较容易做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 ISN” t用于HeavyOperation,它可以从PerformTaskAction签名中删除。

+0

谢谢史蒂芬,修正任务修正其中两个如你所建议的,突出的一个“sb.Append(string.Format(”{0}“,tasks.Add(Task.Run(()=> HeavyOperation(i。 ToString())))));“基本上这四个任务会被触发,并且在HeavyOperation im试图返回任务的结果,然后为每个返回的结果附加字符串构建器,然后在所有任务完成之后返回字符串生成器对象与结果填充窗体上的文本框(如果这样做有道理?)谢谢 –

+0

已更新显示一个更简单的方法。 –

+0

谢谢史蒂芬,工作:) –

0

改变方法签名

static async Task<string> PerfromTaskAction(CancellationToken ct) 

return Task(sb.ToString()); 

然后

textBox1.Text = await Task.Run(() => PerfromTaskAction(cancelSource.Token), cancelSource.Token).Result; 
相关问题