Первый ответ по существу правильный, но если вам нужен самый простой способ добиться желаемого результата, вот пример отдельного кода, демонстрирующий, как это сделать с помощью семафора (так же, как группы отправки работают за кулисами , JFYI):
#include <dispatch/dispatch.h>
#include <stdio.h>
main()
{
dispatch_queue_t myQ = dispatch_queue_create("my.conQ", DISPATCH_QUEUE_CONCURRENT);
dispatch_semaphore_t mySem = dispatch_semaphore_create(0);
dispatch_async(myQ, ^{ printf("Hi I'm block one!\n"); sleep(2); dispatch_semaphore_signal(mySem);});
dispatch_async(myQ, ^{ printf("Hi I'm block two!\n"); sleep(4); dispatch_semaphore_signal(mySem);});
dispatch_async(myQ, ^{ dispatch_semaphore_wait(mySem, DISPATCH_TIME_FOREVER); printf("Hi, I'm the final block!\n"); });
dispatch_main();
}
-121--3702229-Это достаточное условие может быть ослаблено, как обсуждалось ниже в разделе Выборка сигналов без основной полосы частот.
Более поздние утверждения теоремы иногда осторожны, чтобы исключить условие равенства; то есть условие заключается в том, что x (t) не содержит частот, превышающих или равных В; это условие эквивалентно условию Шеннона, за исключением тех случаев, когда функция включает в себя устойчивую синусоидальную составляющую с точной частотой B.
У меня есть веб-страница с парой дремлющих мультиагентных симуляций netlogo . Я использую netlogo для преподавания, и я обнаружил, что, как только вы преодолеваете кривую обучения, вы можете разрабатывать симуляции удивительно быстро. То, что займет 80 человеко-часов в других так называемых агентских средах (Jade, Repast, которые действительно в основном являются просто библиотеками программирования), может быть сделано за 2 часов.
С другой стороны, netlogo на самом деле не подходит для моделирования, которое требует огромного количества деталей, например, имитация сети на всем пути от TCP/IP до HTTP. Это просто потребует большого количества кода, независимо от языка программирования, и netlogo в настоящее время отстой, если ваша программа в конечном итоге больше, чем 10 страниц. Сказав это, большинство людей были бы поражены тем, что можно сделать на 10 страницах кода netlogo.
-121--2774053- Целью класса BackgroundWorker
является выполнение работы с потоком , не являющимся GUI , в то время как GUI остается отзывчивым. Если вы не устанавливаете Контроль. CheckForIllegalCrossThreadCalls
к ложный
(который вы не должны делать), или использование Призывает
, как предложено в других ответах (который я также не рекомендовал бы), вы собираетесь получить незаконное операционное исключение поперечной нити.
Если необходимо, чтобы связанные с GUI "вещи" происходили во время работы BackgroundWorker
, обычно рекомендуется использовать метод BackgroundWorker.EventProgress
и присоединить соответствующий обработчик к событию BackgroundWorker.ProgressChanged
. Если вы хотите, чтобы что-то произошло в графическом интерфейсе пользователя после завершения BackgroundWorker
, просто подключите обработчик для обновления графического интерфейса к событию BackgroundWorker.RunWorureCompleted
.
Вы не можете напрямую установить свойство элемента управления, которое находится в потоке пользовательского интерфейса из другого потока. Однако это можно сделать, вот пример из msdn.
Private Sub SetText(ByVal [text] As String)
' InvokeRequired required compares the thread ID of the'
' calling thread to the thread ID of the creating thread.'
' If these threads are different, it returns true.'
If Me.textBox1.InvokeRequired Then
Dim d As New SetTextCallback(AddressOf SetText)
Me.Invoke(d, New Object() {[text]})
Else
Me.textBox1.Text = [text]
End If
End Sub
Где именно вы устанавливаете свойство Enabled
? Если вы делаете это в обработчике события DoWork
, то этот код выполняется в другом потоке, чем тот, в котором была создана кнопка, что и приводит к возникновению исключения. Чтобы обойти это, следует использовать BeginInvoke
. Для удобства его можно обернуть в метод, например, так:
Private Sub SetControlEnabled(ByVal ctl As Control, ByVal enabled As Boolean)
If ctl.InvokeRequired Then
ctl.BeginInvoke(New Action(Of Control, Boolean)(AddressOf SetControlEnabled), ctl, enabled)
Else
ctl.Enabled = enabled
End If
End Sub
Теперь вы можете безопасно вызвать этот метод для включения или отключения любого элемента управления из любого потока:
SetControlEnabled(someButton, False)