C# NET使用异步方法防止用户同时调用API两次 使用系统; 使用系统线程; 命名空间示例.AdvancedProgramming.AsynchronousOperations { 公共类AsyncMain { 公共静态void Main() { //异步方法将线程id放在这里。 int-threadId; //创建测试类的实例。 AsyncDemo ad=新的AsyncDemo(); //创建委托。 AsyncMethodCaller=新的AsyncMethodCaller(ad.TestMethod); //启动非同步呼叫。 IAsyncResult result=caller.BeginInvoke(3000, out-threadId,null,null); 睡眠(0); WriteLine(“主线程{0}执行一些工作。”, Thread.CurrentThread.ManagedThreadId); //调用EndInvoke以等待异步调用完成, //并检索结果。 string returnValue=caller.EndInvoke(out-threadId,result); WriteLine(“在线程{0}上执行的调用,返回值为\“{1}\”, threadId,returnValue); } } }

C# NET使用异步方法防止用户同时调用API两次 使用系统; 使用系统线程; 命名空间示例.AdvancedProgramming.AsynchronousOperations { 公共类AsyncMain { 公共静态void Main() { //异步方法将线程id放在这里。 int-threadId; //创建测试类的实例。 AsyncDemo ad=新的AsyncDemo(); //创建委托。 AsyncMethodCaller=新的AsyncMethodCaller(ad.TestMethod); //启动非同步呼叫。 IAsyncResult result=caller.BeginInvoke(3000, out-threadId,null,null); 睡眠(0); WriteLine(“主线程{0}执行一些工作。”, Thread.CurrentThread.ManagedThreadId); //调用EndInvoke以等待异步调用完成, //并检索结果。 string returnValue=caller.EndInvoke(out-threadId,result); WriteLine(“在线程{0}上执行的调用,返回值为\“{1}\”, threadId,returnValue); } } },c#,multithreading,C#,Multithreading,EndInvoke可能会阻止调用线程,因为它在异步调用完成之前不会返回 我将在API中实现EndInvoke,以防止用户调用API两次。 我是否使用正确的方法防止同一用户同时调用API两次?如果我可以假设AsyncDemo的实现如下所示: 公共类异步演示 { //要异步执行的方法。 公共字符串测试方法(int callDuration,out int threadId) { 控制台。WriteLine(“测试方法开始”); 睡眠(callDuration); threadId=Thread.Cu

EndInvoke
可能会阻止调用线程,因为它在异步调用完成之前不会返回

我将在API中实现
EndInvoke
,以防止用户调用API两次。
我是否使用正确的方法防止同一用户同时调用API两次?

如果我可以假设
AsyncDemo
的实现如下所示:

公共类异步演示
{
//要异步执行的方法。
公共字符串测试方法(int callDuration,out int threadId)
{
控制台。WriteLine(“测试方法开始”);
睡眠(callDuration);
threadId=Thread.CurrentThread.ManagedThreadId;
返回string.Format(“我的调用时间是{0}.”,callDuration.ToString());
}
}
相关的
AsyncMethodCaller
委托定义如下:

公共委托字符串AsyncMethodCaller(int callDuration,out int threadId);
根据.NET版本的不同,您有两个选项:

.NET框架 在这里,我们可以使用
任务.fromsync
()将APM模型转换为TPL。
我必须定义两个助手方法(
Begin
End
)来将额外的参数传递给
TestMethod

End
方法返回一个元组
(字符串,int)
,以避免
out
参数。()

公共静态异步任务Main() { var ad=新的AsyncDemo(); AsyncMethodCaller=ad.TestMethod; IAsyncResult Begin(异步回调cb,对象状态=null) =>caller.BeginInvoke(3000,out,cb,state); (字符串,int)结束(IAsyncResult iar) { var result=caller.EndInvoke(out-var-threadId,iar); 返回(结果,线程ID); }; var task1=Task.Factory.fromsync(开始、结束、null); var task2=Task.Factory.fromsync(开始、结束、空); 等待任务。WhenAll(任务1,任务2); var(result1,threadId1)=等待任务1; var(result2,threadId2)=等待任务1; WriteLine($“{threadId1}:{result1}”); WriteLine($“{threadId2}:{result2}”); } 产出将是:

Test method begins.
Test method begins.
3: My call time was 3000.
3: My call time was 3000.
Test method begins.
Test method begins.
4: My call time was 3000.
5: My call time was 3000.
.NET核心 这里我们不能使用
BeginInvoke
,因为它会抛出
PlatformNotSupportedException

下面是
任务的用法。运行

static async Task Main(字符串[]args)
{
int-threadId1=0,threadId2=0;
var ad=新的AsyncDemo();
AsyncMethodCaller=ad.TestMethod;
var task1=Task.Run(()=>caller(3000,out-threadId1));
var task2=Task.Run(()=>caller(3000,out-threadId2));
等待任务。WhenAll(任务1,任务2);
WriteLine($“{threadId1}:{await task1}”);
WriteLine($“{threadId2}:{await task2}”);
}
产出将是:

Test method begins.
Test method begins.
3: My call time was 3000.
3: My call time was 3000.
Test method begins.
Test method begins.
4: My call time was 3000.
5: My call time was 3000.

Begin
End
类型方法是一种较旧的APM模型,主要用于处理异步编程的较旧方法。它与线程安全、锁定或阻止某人同时调用一个方法两次无关。您必须自己使用类似于
lock
@JohnWalker的同步原语来实现这一点。您能否与我们共享
AsyncDemo
类定义?您的
AsyncMethodCaller
委托是如何定义的?他们的定义是什么?这里的实际目标是什么?您是否有要保护的非线程安全API?如果是这样的话,一个简单的锁或者一个任务队列就更合适了。什么浏览器??这是一个控制台应用程序。没有浏览器。未阻止任何内容,
wait
等待已存在的操作完成,而不阻止被调用方。我怀疑您真正的问题与BeginInvoke或tasks无关。你认为BeginInvoke是解决方案,所以你问了这个问题。实际问题是什么?或者在这两种情况下都使用
Task.Run(()=>ad.TestMethod())
。是的,这更简单:D@PeterCsala所以这种方法只等待用户完成任务,防止用户调用API两次,我的系统能够多次登录,比如用户在firefox中登录,在google chrome中登录,同时单击按钮以请求API。此方法是否可以解决问题?@JohnWalker我提供的示例不调用任何API。因为您原来的问题没有指定
TestMethod
做什么,所以我不能回答您的新问题。