背景
我正在更新舊版軟體庫。遺留代碼使用無限回圈 System.Threading.Thread 執行佇列中的行程。這些行程對另一個只能處理一個請求的遺留系統執行多個請求。
我正在嘗試進行現代化改造,但我是 WCF 服務的新手,我的知識中可能存在一個可以簡化事情的大漏洞。
WCF 客戶端主機
在現代化程序中,我正在嘗試遷移到客戶端 WCF 服務。WCF 服務允許對來自多個應用程式的請求進行排隊。該服務接受一個請求并回傳一個 GUID,以便我可以通過回呼正確關聯。
public class SomeService : ISomeService
{
public Guid AddToQueue(Request request)
{
// Code to add the request to a queue, return a Guid, etc.
}
}
public interface ISomeCallback
{
void NotifyExecuting(Guid guid)
void NotifyComplete(Guid guid)
void NotifyFault(Guid guid, byte[] data)
}
WCF 客戶端行程佇列
我遇到的問題是遺留流程可以包含多個請求。行程 1 可能會執行請求 X,然后執行請求 Y,并根據這些結果跟進請求 Z。對于遺留系統,可能會有行程 1-10 排隊。
我有一個執行該程序的笨拙模型。我正在處理行程中的事件以了解它何時完成或失敗。但是,感覺真的很坑爹……
public class ActionsQueue
{
public IList<Action> PendingActions { get; private set; }
public Action CurrentAction { get; private set; }
public void Add(Action action)
{
PendingAction.Add(action)
if (CurrentAction is null)
ExecuteNextAction();
}
private void ExecuteNextAction()
{
if (PendingActions.Count > 0)
{
CurrentAction = PendingActions[0];
PendingActions.RemoveAt(0);
CurrentAction.Completed = OnActionCompleted;
CurrentAction.Execute();
}
}
private OnActionCompleted(object sender, EventArgs e)
{
CurrentAction = default;
ExecuteNextAction();
}
}
public class Action
{
internal void Execute()
{
// Instantiate the first request
// Add handlers to the first request
// Send it to the service
}
internal void OnRequestXComplete()
{
// Use the data that's come back from the request
// Proceed with future requests
}
}
通過客戶端回呼,GUID 與原始請求相匹配,并在原始請求上引發相關事件。同樣,這里的實作感覺非常笨拙。
我已經看到主機的異步方法示例,回傳一個任務,然后在任務上使用等待。但是,我也看到了不要這樣做的建議。
任何關于如何將這種混亂解開成更有用的東西的建議都值得贊賞。同樣,我的知識可能存在漏洞,這使我無法獲得更好的解決方案。
謝謝
uj5u.com熱心網友回復:
WCF 的客戶端和服務器之間的佇列通信通常可以使用 NetMsmqbinding 進行,它確保客戶端和服務器之間的持久通信。有關具體示例,請參閱本文。
如果您需要高效快速的訊息處理,請使用非事務性佇列并將 ExactlyOnce 屬性設定為 False,但這會影響安全。檢查此檔案以獲取更多資訊。
uj5u.com熱心網友回復:
萬一有人后來遇到類似的問題,這是我最終得到的粗略草圖:
[ServiceContract(Name="MyService", SessionMode=Session.Required]
public interface IMyServiceContract
{
[OperationContract()]
Task<string> ExecuteRequestAsync(Action action);
}
public class MyService: IMyServiceContract
{
private TaskQueue queue = new TaskQueue();
public async Task<string> ExecuteRequestAsync(Request request)
{
return await queue.Enqueue(() => request.Execute());
}
}
public class TaskQueue
{
private SemaphoreSlim semaphore;
public TaskQueue()
{
semaphore = new SemaphoreSlim(1);
}
Task<T> Enqueue<T>(Func<T> function)
{
await semaphore.WaitAsync();
try
{
return await Task.Factory.StartNew(() => function.invoke();)
}
finally
{
semaphore.Release();
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/512559.html
標籤:C#。网wcf异步
上一篇:錯誤:PlatformNotSupportedException:不支持組態檔或.NETCore6如何使用SOAP.NETFrameworkwcf
