C# 线程屏障问题
我需要一个线程等待另一个线程提供数据。我创建了这个类:C# 线程屏障问题,c#,multithreading,asynchronous,C#,Multithreading,Asynchronous,我需要一个线程等待另一个线程提供数据。我创建了这个类: 公共类异步对象等待 { 私有void\u超时(时间跨度超时,TaskCompletionSource tcs) { 系统线程线程睡眠(超时); 锁(tcs) { if(!tcs.TrySetException(新的TimeoutException(“等待超时”)) { int a=0; } 其他的 { 控制台写入线(“超时”); } } } 公共任务WaitOneAsync(TimeSpan超时) { TaskCompletionSourc
公共类异步对象等待
{
私有void\u超时(时间跨度超时,TaskCompletionSource tcs)
{
系统线程线程睡眠(超时);
锁(tcs)
{
if(!tcs.TrySetException(新的TimeoutException(“等待超时”))
{
int a=0;
}
其他的
{
控制台写入线(“超时”);
}
}
}
公共任务WaitOneAsync(TimeSpan超时)
{
TaskCompletionSource wait=新建TaskCompletionSource();
锁定(_等待)
{
_等待。排队(等待);
Task.Run(()=>
{
_超时(超时,等待);
});
}
返回等待任务;
}
公用bool TrySetOne(触发器类型触发器、转换器)
{
TaskCompletionSource等待;
布尔集=假;
锁定(_等待)
{
while(!set)&&(!(_waits.Count==0))//当我们还没有完成一项任务时,只要我们还有更多的任务要检查。
{
;//等待下一次。
lock(_waits.Peek())//等待任何其他线程停止使用下一个线程,等待它,然后获得独占访问权。
{
wait=_waits.Peek();
if(EqualityComparer.Default.Equals(转换器(触发器),_值))
{
set=wait.TrySetResult(trigger);//尝试设置结果以完成任务。如果无法完成,请尝试下一个任务
_waits.Dequeue();
如果(!set)
{
持续
}
其他的
{
返回true;
}
}
其他的
{
返回false;
}
}
}
返回false;
}
}
}
要做到这一点,还要提供一个基于任务的界面,在等待时不会冻结我的UI。 不过,这似乎有个问题。调用Recieve()方法时,WaitFor生成的任务可能需要一秒钟的时间来接收完成信息。我找不到这样做的理由
这可能是由于异步方法开销造成的吗?还有其他不太复杂的方法吗?请用小样本编辑您的问题,以显示您的问题。您可能希望使用回调样式的实现,并执行Interlocked.CompareExchange()来设置一个标记,以便UI经常检查。这需要一秒钟,因为您有一个线程。Sleep,我猜你是在告诉它睡一会儿。请在这里的StackOverflow上贴上最短的代码。@ginkner,你只是想给任务加一个超时吗?
public class AsyncObjectWait<T1, TriggerType>
{
private void _timeout(TimeSpan timeout, TaskCompletionSource<TriggerType> tcs)
{
System.Threading.Thread.Sleep(timeout);
lock (tcs)
{
if (!tcs.TrySetException(new TimeoutException("Wait Timed Out")))
{
int a = 0;
}
else
{
Console.WriteLine("Timed Out");
}
}
}
public Task<TriggerType> WaitOneAsync(TimeSpan timeout)
{
TaskCompletionSource<TriggerType> wait = new TaskCompletionSource<TriggerType>();
lock (_waits)
{
_waits.Enqueue(wait);
Task.Run(() =>
{
_timeout(timeout, wait);
});
}
return wait.Task;
}
public bool TrySetOne(TriggerType trigger, Converter<TriggerType, T1> converter)
{
TaskCompletionSource<TriggerType> wait;
bool set = false;
lock (_waits)
{
while ((!set) && (!(_waits.Count == 0))) //while we havent completed a task, and as long as we have some more to check.
{
; //get the next wait.
lock (_waits.Peek()) //wait for any other threads to stop using the next wait it, then get exclusive access.
{
wait = _waits.Peek();
if (EqualityComparer<T1>.Default.Equals(converter(trigger), _value))
{
set = wait.TrySetResult(trigger); //try and set the result to complete the task. if we cant, try the next task
_waits.Dequeue();
if (!set)
{
continue;
}
else
{
return true;
}
}
else
{
return false;
}
}
}
return false;
}
}
}