Reputation: 21
I have a public string
called simply m
. The code shall only proceed when m
is not null
anymore. As long as m
is null
it should just wait. Any suggestions on how to do that? ( Without pausing the entire program, otherwise m
would never change)
Upvotes: 1
Views: 4470
Reputation: 14991
You can use a TaskCompletionSource<TResult>
.
Create a new instance, and anywhere that needs to wait for the string to be available, you can use await tcs.Task
. When whatever produces the string finishes, you call tcs.SetResult(result)
.
This allows your code to avoid busy-loops, as one other answer suggested, and if you have a highly concurrent application, it avoids blocking threads, as another answer suggested.
Upvotes: 5
Reputation: 3285
If you are looking for a simple async solution with a small latency:
await Task.Run(async () => { while (string.IsNullOrWhiteSpace(m)) await Task.Delay(10); });
or
while (string.IsNullOrWhiteSpace(m)) await Task.Delay(10);
Upvotes: 3
Reputation: 10563
I am assuming we're talking about a multi-threaded environment. Refer to Condition Variables in C#/.NET. You can use the Monitor
class, but you need to change your public field to a property (which you should do anyway).
private readonly string? _m;
public string? M
{
get => _m;
set
{
lock (_m)
{
_m = value;
if (_m != null)
{
Monitor.PulseAll(_m);
}
}
}
}
public void Foo()
{
lock (_m)
{
while (_m == null)
{
Monitor.Enter(_m);
}
// Code using the _m resource...
}
// Rest of your code...
}
This will work and is enough if you have a small number of threads and locking will be rather rare. If there are multiple threads reading from and writing to _m
, this might be unperformant and you might want to mix this with a ReaderWriterLockSlim
](https://learn.microsoft.com/en-us/dotnet/api/system.threading.readerwriterlockslim?view=netstandard-2.1) to optimise for the common case of _m
not being null.
Upvotes: 0
Reputation: 159
How about turning your "public string
" into a property?
private string _m
public string M
{
get => _m;
set
{
if (value != _m)
{
_m = value;
if (string.IsNullOrEmpty(value))
{
DoSomething(value);
}
}
}
}
Upvotes: 2
Reputation: 381
The simplest solution in this case is write a while(true) loop and add if statement which checks string is null or not. But this will keep consuming CPU cycles unnecessarily. So I suggest you to implement conditional wait which will basically trigger your code once the condition is matched (string becomes null in your case) and will not waste CPU cycles in just waiting.
Upvotes: 0