需要帮助在 c# 中同步控制事件处理程序
Need help controlling event handler synchronously in c#
我有如下代码片段:
public void PopulateItemList()
{
foreach(var item in collection)
{
bool isSuccess = GetSubItem(item.Id);
if(!isSuccess)
{
ShowError();
break;
}
}
}
public bool GetSubItem(string parentId)
{
bool isSuccess = false;
_service.Communication<ViewModel, Request, Response>((ViewModel vm, ref Request) =>
{
request.ApiName = Const.FXXXName;
request.Id = parentId;
}, (viewModel, response, error) =>
{
DoSomething();
...
isSuccess = response.IsOk; // I put a breakpoint here
}
return isSuccess; // I also put a breakpoint here
}
Communication函数原型如下:
public void Communication<VM, S, R>(WebSocketOut<VM, S) send, WebSocketIn<VM, R> recv)
其中 WebSocketIn 和 WebSocketOut 是两个委托。问题是当我调试程序时,"return isSuccess;" 语句在收到来自 "response.IsOk" 的结果之前总是 运行 所以该函数的 returned 值总是 "false"。也就是说,执行顺序是:
- return 成功
- isSuccess = response.IsOk(在 MessageReceived(WebSocket4Net) 事件触发后)
我不知道如何运行倒序。任何意见、建议或帮助将不胜感激。
谢谢
您可以使用async/await and TaskCompletionSource
async public void PopulateItemList() //!!async keyword
{
foreach(var item in collection)
{
bool isSuccess = await GetSubItem(item.Id); //!!await
if(!isSuccess)
{
ShowError();
break;
}
}
}
public Task<bool> GetSubItem(string parentId)
{
var tcs = new TaskCompletionSource<bool>(); //!!
_service.Communication<ViewModel, Request, Response>((ViewModel vm, ref Request) =>
{
request.ApiName = Const.FXXXName;
request.Id = parentId;
}, (viewModel, response, error) =>
{
DoSomething();
...
tcs.SetResult(response.IsOk); //!!
}
return tcs.Task;
}
尝试使用 AutoResetEvent 等待异步功能完成。
public bool GetSubItem(string parentId)
{
System.Threading.AutoResetEvent autoEvent = new System.Threading.AutoResetEvent(false);
bool isSuccess = false;
ThreadPool.QueueUserWorkItem((o) =>
{
_service.Communication<ViewModel, Request, Response>((ViewModel vm, ref Request) =>
{
request.ApiName = Const.FXXXName;
request.Id = parentId;
}, (viewModel, response, error) =>
{
DoSomething();
...
isSuccess = response.IsOk; // I put a breakpoint here
autoEvent.Set();
}
});
autoEvent.WaitOne();
return isSuccess; // I also put a breakpoint here
}
我有如下代码片段:
public void PopulateItemList()
{
foreach(var item in collection)
{
bool isSuccess = GetSubItem(item.Id);
if(!isSuccess)
{
ShowError();
break;
}
}
}
public bool GetSubItem(string parentId)
{
bool isSuccess = false;
_service.Communication<ViewModel, Request, Response>((ViewModel vm, ref Request) =>
{
request.ApiName = Const.FXXXName;
request.Id = parentId;
}, (viewModel, response, error) =>
{
DoSomething();
...
isSuccess = response.IsOk; // I put a breakpoint here
}
return isSuccess; // I also put a breakpoint here
}
Communication函数原型如下:
public void Communication<VM, S, R>(WebSocketOut<VM, S) send, WebSocketIn<VM, R> recv)
其中 WebSocketIn 和 WebSocketOut 是两个委托。问题是当我调试程序时,"return isSuccess;" 语句在收到来自 "response.IsOk" 的结果之前总是 运行 所以该函数的 returned 值总是 "false"。也就是说,执行顺序是:
- return 成功
- isSuccess = response.IsOk(在 MessageReceived(WebSocket4Net) 事件触发后)
我不知道如何运行倒序。任何意见、建议或帮助将不胜感激。
谢谢
您可以使用async/await and TaskCompletionSource
async public void PopulateItemList() //!!async keyword
{
foreach(var item in collection)
{
bool isSuccess = await GetSubItem(item.Id); //!!await
if(!isSuccess)
{
ShowError();
break;
}
}
}
public Task<bool> GetSubItem(string parentId)
{
var tcs = new TaskCompletionSource<bool>(); //!!
_service.Communication<ViewModel, Request, Response>((ViewModel vm, ref Request) =>
{
request.ApiName = Const.FXXXName;
request.Id = parentId;
}, (viewModel, response, error) =>
{
DoSomething();
...
tcs.SetResult(response.IsOk); //!!
}
return tcs.Task;
}
尝试使用 AutoResetEvent 等待异步功能完成。
public bool GetSubItem(string parentId)
{
System.Threading.AutoResetEvent autoEvent = new System.Threading.AutoResetEvent(false);
bool isSuccess = false;
ThreadPool.QueueUserWorkItem((o) =>
{
_service.Communication<ViewModel, Request, Response>((ViewModel vm, ref Request) =>
{
request.ApiName = Const.FXXXName;
request.Id = parentId;
}, (viewModel, response, error) =>
{
DoSomething();
...
isSuccess = response.IsOk; // I put a breakpoint here
autoEvent.Set();
}
});
autoEvent.WaitOne();
return isSuccess; // I also put a breakpoint here
}