我目前正在创建多个Threads
来调用一个函数来检查while loop
内的语句是否为真。
我的问题:
我创建了10个不同的线程,它们同时运行相同的功能,到目前为止工作正常。但是一旦bool isAviable
变为true,else check中的其他代码将被执行10次,因为有10个线程正在运行。
一旦bool isAviable变为true,我能以某种方式停止其他线程并继续使用1个线程吗?
示例如何启动线程:
for(int i = 0; i < 10; i++)
{
new Thread(new ThreadStart(function)) { IsBackground = true }.Start();
}
被调用的函数示例:
private void function()
{
try
{
bool isAviable = false;
while (isAviable == false)
{
isAviable = checkFunction(bunifuMetroTextbox3.Text);
if (isAviable == false)
{
base.Invoke(new Action(method_5));
}
else
{
// Ececute other function code which should only be executed by one thread..
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
示例checkFunction:
private bool checkFunction(string handle)
{
bool aviable = false;
while (!aviable)
{
using (WebClient client = new WebClient())
{
try
{
if (client.DownloadString("http://url.com/script.php?user=" + handle).Contains("No users found"))
{
return true;
}
else
{
return false;
}
}
catch(WebException ex)
{
MessageBox.Show(ex.Message);
}
}
}
return false;
}
答案 0 :(得分:2)
因此,由于您正在进行的工作是IO绑定,而不是CPU绑定,因此您不应该创建新线程。你应该只是为你的IO使用异步方法,以保持你的UI响应,而不是创建只是花费他们所有时间坐在什么都不做的线程。这是对您的方法进行的一项简单的更改,可以检查给定用户是否可用:
private async Task<bool> IsUserAvaliable(string handle)
{
while (true)
{
using (HttpClient client = new HttpClient())
{
try
{
string content = await client.GetStringAsync("http://url.com/script.php?user=" + handle);
return content.Contains("No users found");
}
catch (WebException ex)
{
MessageBox.Show(ex.Message);
}
}
}
}
接下来,对于调用方法,它从根本上简化了代码,使其简单地表示确定用户何时可用,而不考虑在以下情况下需要执行的操作:
private async Task CheckUntilUserIsAvaliable()
{
//presumably bunifuMetroTextbox3 shouldn't be hard coded, but instead passed in, but it's unclear
while (!await IsUserAvaliable(bunifuMetroTextbox3.Text))
{
method_5();
await Task.Delay(1000); //adjust as appropriate for what the poll time should be
}
}
接下来,我们可以创建一个方法来调用CheckUntilUserIsAvaliable
10次不同的时间,我们可以使用WhenAny
来确定其中任何一个完成的时间。在其中一个完成后,我们可以在第一个用户可用时完成任何需要完成的工作:
private async Task CheckUntilOneOfTheUsersIsAvaliable()
{
await Task.WhenAny(Enumerable.Range(0, 10)
.Select(i => CheckUntilUserIsAvaliable()));
//Work to be done when any one of the checking operations has indicated that it's avalaible
}