我有一个名为Connect()的函数,这个函数大约需要2-3秒,因为它使用了一些api请求。现在我想找到一种方法,让我的Ui不会在生病时启动这个功能。
private void connectToolStripMenuItem_Click(object sender, EventArgs e)
{
Connect() // << this tooks a lot of time
}
我试图用线程解决它
private void connectToolStripMenuItem_Click(object sender, EventArgs e)
{
new Thread(Connect).Start();
}
和一个backgroudnworker
private void backgroundWorkerConnect_DoWork(object sender, DoWorkEventArgs e)
{
Connect();
}
但程序仍然冻结。
private void Connect()
{
if (InvokeRequired)
{
Invoke(new MethodInvoker(Connect));
}
else
{
if (!connected)
{
connected = true;
verbindenToolStripMenuItem.Enabled = false;
trennenToolStripMenuItem.Enabled = true;
InfoStripStatus.Text = "Status: Connected";
irc.joinRoom(channel, BotConnectingMessage);
chatThread = new Thread(getMessage);
chatThread.Start();
loadLoyalty();
updateTimer = new System.Threading.Timer(timerViewer, null, 0, 60000);
}
}
}
也许我只是做错了什么,希望有人可以帮助我。
答案 0 :(得分:2)
使用另一个线程(无论是通过BackgroundWorker
还是直接创建一个)来调用一个方法,除了在UI线程上调用某些代码然后再等待它之外,将会什么都不解决。您关心的代码仍然在UI线程中执行,阻止它。
您应该使用async
/ await
与Task.Run()
来处理您的工作:
private async void connectToolStripMenuItem_Click(object sender, EventArgs e)
{
await Connect();
}
private async Task Connect()
{
if (!connected)
{
connected = true;
verbindenToolStripMenuItem.Enabled = false;
trennenToolStripMenuItem.Enabled = true;
InfoStripStatus.Text = "Status: Connected";
await Task.Run(() => irc.joinRoom(channel, BotConnectingMessage));
chatThread = new Thread(getMessage);
chatThread.Start();
loadLoyalty();
updateTimer = new System.Threading.Timer(timerViewer, null, 0, 60000);
}
}
根据loadLoyalty()
的速度而定,您可能还需要await Task.Run(loadLoyalty);
,而不是直接调用它。
上面将执行它所属的UI线程中的所有代码,除了您通过Task.Run()
调用的代码。
还有其他方法可以重构代码,包括与BackgroundWorker
一起使用的替代方法(即只使用Control.Invoke()
执行前四个语句,并在{{1方法直接)。但恕我直言,上面使用Connect()
/ async
是今天最好的选择。
答案 1 :(得分:0)
好的,看起来很有意思。我将尝试将其转移到其他函数,因为我发现它是updateTimer冻结它。
private void timerViewer(object state)
{
irc.sendChatMessage("/mods");
UpdateStream();
UpdateChatters();
}
private void UpdateStream()
{
if (InvokeRequired)
{
Invoke(new MethodInvoker(UpdateStream));
}
else
{
StreamInformations = TwitchROClient.getStream(TwitchROClient.getIDbyUsername("xzaliax"));
if (StreamInformations.stream != null)
{
viewers = StreamInformations.stream.Viewers;
totalviews = StreamInformations.stream.channel.Views;
if (followers == 0)
{
followers = StreamInformations.stream.channel.Followers;
}
else
{
if (followers < StreamInformations.stream.channel.Followers)
{
newFollower();
}
followers = StreamInformations.stream.channel.Followers;
}
InfoStripViewer.Text = "| " + string.Format(CultureInfo.InvariantCulture, "{0:N0}", viewers).Replace(',', '.') + " :Viewer";
InfoStripFollower.Text = "| " + string.Format(CultureInfo.InvariantCulture, "{0:N0}", followers).Replace(',', '.') + " :Follower ";
InfoStripTotalViewer.Text = "| " + string.Format(CultureInfo.InvariantCulture, "{0:N0}", totalviews).Replace(',', '.') + " :Total Viewers";
InfoStripStream.Text = "| Stream: Online";
}
else
{
InfoStripViewer.Text = "| -- :Viewer";
InfoStripFollower.Text = "| -- :Follower";
InfoStripTotalViewer.Text = "| -- :Total Viewers";
InfoStripStream.Text = "| Stream: Offline";
}
}
}
private void UpdateChatters()
{
if (InvokeRequired)
{
Invoke(new MethodInvoker(UpdateChatters));
}
else
{
ChannenlChatters = TwitchROClient.getChatters(channel);
lbViewer.Items.Clear();
if (ChannenlChatters != null)
{
if (ChannenlChatters.AllChatters != null)
{
tbChat.Text += "Checking the viewer list..." + Environment.NewLine;
if (ChannenlChatters.AllChatters.Admins.Count >= 0) lbViewer.Items.Add("_____________Admins_____________");
foreach (string admin in ChannenlChatters.AllChatters.Admins)
{
lbViewer.Items.Add(String.Format("{0,5}", admin));
}
if (ChannenlChatters.AllChatters.Admins.Count >= 0) lbViewer.Items.Add("");
if (ChannenlChatters.AllChatters.Staff.Count >= 0) lbViewer.Items.Add("_____________Stuff______________");
foreach (string stuff in ChannenlChatters.AllChatters.Staff)
{
lbViewer.Items.Add(String.Format("{0,5}", stuff));
}
if (ChannenlChatters.AllChatters.Staff.Count >= 0) lbViewer.Items.Add("");
if (ChannenlChatters.AllChatters.GlobalMods.Count >= 0) lbViewer.Items.Add("___________Global Mods__________");
foreach (string globalmods in ChannenlChatters.AllChatters.GlobalMods)
{
lbViewer.Items.Add(String.Format("{0,5}", globalmods));
}
if (ChannenlChatters.AllChatters.GlobalMods.Count >= 0) lbViewer.Items.Add("");
foreach (string globalMods in ChannenlChatters.AllChatters.GlobalMods)
{
lbViewer.Items.Add(String.Format("{0,5}", globalMods));
}
if (ChannenlChatters.AllChatters.Moderators.Count >= 0) lbViewer.Items.Add("___________Moderators___________");
foreach (string moderator in ChannenlChatters.AllChatters.Moderators)
{
lbViewer.Items.Add(String.Format("{0,5}", moderator));
}
if (ChannenlChatters.AllChatters.Viewers.Count >= 0) lbViewer.Items.Add("____________Viewers_____________");
foreach (string viewers in ChannenlChatters.AllChatters.Viewers)
{
lbViewer.Items.Add(String.Format("{0,5}", viewers));
}
}
}
}
}
所以我会阅读更多有关ascny的信息并等待并稍微测试一下