问题
So I am trying to implement multi-threading in my windows forms project. I know of one way to do this, by creating a new thread for the methods you want to run separately like this:
Thread t = new Thread(new ThreadStart(methodName));
t.Start();
And then invoking each object that is "Accessed from a thread other than the thread it was created on." like this:
this.Invoke(new MethodInvoker(delegate()
{
this.Object = "whatever";
}));
The only problem with this is, my program is several thousand lines long, and I make the references all the time. So putting a method invoker around every little thing I want to change in another thread seems horribly inefficient and Im sure there is a better way but I cant seem to find it online so I figured why not ask you guys.
Is there something I can say at the beginning of the method that will automatically delegate objects if they are referenced outside the thread? Because if there isnt another way, my code is probably going to turn out real messy and hard to read. :(
Edit: Here is a larger chunk of the code, maybe it will make this a bit clearer:
foreach (var lines in serversToRunTextBox.Lines)
{
manipulationTextBox.Text = lines;
string line = manipulationTextBox.Text;
string scriptWithWild = actualScriptTextBox.Text.Replace(wildCard.ToString(), line);
shellStream.WriteLine(scriptWithWild);
Thread.Sleep(100);
client.RunCommand(scriptWithWild);
//MessageBox.Show(scriptWithWild);
Thread.Sleep(2500);
reply = shellStream.Read();
if (reply.Contains("denied"))
{
MessageBox.Show("You must have sudo access for this command", "No Sudo", MessageBoxButtons.OK, MessageBoxIcon.Hand);
}
else
{
this.Invoke(new MethodInvoker(delegate()
{
actualResultsTextBox.AppendText(reply + "\n \n");
}));
回答1:
One way to deal with this is to leverage the async/await feature which was shipped with C# 5.0.
private async Task DoSomethingAsync()
{
//Some code
string text = await GetSomeTextAsync(somrParam);
statusTextBox.Text = text;//Will execute in captured context
//Some more code
}
Code after the await
keyword will execute in the captured context. So if you've called the DoSomethingAsync
in UI thread, statusTextBox.Text = text;
will execute in UI thread itself. So you don't need to call this.Invoke
. And the result is "No more ugly code!!".
If you're not familiar with async/await you can start here and here
来源:https://stackoverflow.com/questions/28614490/multi-threading-c-sharp-windows-forms