我有这样的界面:
interface IAuthentication
{
void AuthenticateAsync(string user, string pwhash);
event EventHandler<AuthenticationResult> AuthenticationDone;
}
这可以通过在事件完成时引发事件来起作用。现在,我想将这个机制包装在一个阻塞方法中,该方法在完成后返回验证结果:
AuthenticationResult Authenticate(string user, string pwhash)
{
var auth = GetIAuthenticator();
// ... do something
return <the authentication result from the even argument>;
}
这有可能吗?
答案 0 :(得分:3)
使用等待句柄,您不需要检查一些标志,阻止线程和设置超时:
private AuthenticationResult Authenticate(string user, string pwhash)
{
IAuthentication auth = GetIAuthenticator();
AuthenticationResult result = null;
AutoResetEvent waitHangle = new AutoResetEvent(false);
auth.AuthenticationDone += (o, e) =>
{
result = e;
waitHangle.Set();
};
auth.AuthenticateAsync(user, pwhash);
waitHangle.WaitOne(); // or waitHangle.WaitOne(interval);
return result;
}
答案 1 :(得分:2)
private AuthenticationResult Authenticate(string user, string pwhash)
{
bool isDone = false;
AuthenticationResult results = null
var auth = GetIAuthenticator();
auth.AuthenticationDone += (o, e) =>
{
isDone = true;
results = e;
};
auth.AuthenticateAsync(user, pwhash);
long maxWaitTimeSeconds = 10;
long thresholdMilliseconds = 100;
int countToWait = maxWaitTimeSeconds * 1000 / thresholdMilliseconds;
while (!isDone || countToWait-- > 0)
{
Thread.Sleep(thresholdMilliseconds);
}
if (countToWait == 0 && !isDone)
{
// TODO: timeout handling
}
return results;
}
PS:
如果event args永远不能为null - 你可以删除isDone
变量,只需使用result != null
作为“身份验证完成”指标
答案 2 :(得分:2)
当您使用.Net 4.0时,您可以利用任务并行库。
这是一个非常基本的程序,展示了如何使用TaskCompletionSource
:
public class Test
{
public void Go()
{
ThreadPool.QueueUserWorkItem((z) => this.Imp());
}
private void Imp()
{
Console.WriteLine("Asynchronous operation in progress (1/2)...");
Thread.Sleep(2000);
Console.WriteLine("Asynchronous operation in progress (2/2)...");
if (this.Done != null)
{
this.Done(this, EventArgs.Empty);
}
}
public event EventHandler Done;
}
internal class Program
{
private static void Main(string[] args)
{
Test test = new Test();
TaskCompletionSource<object> tcs = new TaskCompletionSource<object>(null);
Console.WriteLine("Starting asynchronous operation");
Task.Factory.StartNew(() =>
{
test.Done += (sender, e) => tcs.SetResult(null);
test.Go();
});
// Blocking until completion of the async operation
var tmp = tcs.Task.Result;
Console.WriteLine("Asynchronous operation completed");
Console.ReadKey();
}
}
结果是:
Starting asynchronous operation
Asynchronous operation in progress (1/2)...
Asynchronous operation in progress (2/2)...
Asynchronous operation completed
如您所见,执行流程将被阻止,直到异步操作终止。